日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

java 并发 主键_高并发数据库自增主键分析

發(fā)布時間:2023/12/10 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 并发 主键_高并发数据库自增主键分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在一般情況下,在新增領(lǐng)域?qū)ο蠛?#xff0c;都需要獲取對應(yīng)的主鍵值。使用應(yīng)用層來維護(hù)主鍵,在一定程度上有利于程序性能的優(yōu)化和應(yīng)用移植性的提高。在采用數(shù)據(jù)庫自增主鍵的方案里,如果JDBC驅(qū)動不能綁定新增記錄對應(yīng)的主鍵,就需要手工執(zhí)行查詢語句以獲取對應(yīng)的主鍵值,對于高并發(fā)的系統(tǒng),這很容易返回錯誤的主鍵。通過帶緩存的DataFieldMaxValueIncrementer,可以一次獲取批量的主鍵值,供多次插入領(lǐng)域?qū)ο髸r使用,它的執(zhí)行性能是很高的。

我們經(jīng)常使用數(shù)據(jù)的自增字段作為表主鍵,也即主鍵值不在應(yīng)用層產(chǎn)生,而是在新增記錄時,由數(shù)據(jù)庫產(chǎn)生。這樣,應(yīng)用層在保存對象前并不知道對象主鍵值,而必須在保存數(shù)據(jù)后才能從數(shù)據(jù)庫中返回主鍵值。在很多情況下,我們需要獲取新對象持久化后的主鍵值。在Hibernate等ORM框架,新對象持久化后,Hibernate會自動將主鍵值綁定到對象上,給程序的開發(fā)帶來了很多方便。

在JDBC 3.0規(guī)范中,當(dāng)新增記錄時,允許將數(shù)據(jù)庫自動產(chǎn)生的主鍵值綁定到Statement或PreparedStatement中。

使用Statement時,可以通過以下方法綁定主鍵值:int executeUpdate(String sql, int autoGeneratedKeys)

也可以通過Connection創(chuàng)建綁定自增值的PreparedStatement:?PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)

當(dāng)autoGeneratedKeys參數(shù)設(shè)置為Statement.RETURN_GENERATED_KEYS值時即可綁定數(shù)據(jù)庫產(chǎn)生的主鍵值,設(shè)置為Statement.NO_GENERATED_KEYS時,不綁定主鍵值。下面的代碼演示了Statement綁定并獲取數(shù)據(jù)庫產(chǎn)生的主鍵值的過程:

Statement stmt = conn.createStatement();

String sql = "INSERT INTO t_topic(topic_title,user_id) VALUES(‘測試主題’,’123’)";

stmt.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS); // ①指定綁定表自增主鍵值

ResultSet rs = stmt.getGeneratedKeys();

if( rs.next() ) {

intkey = rs.getInt(); // ②獲取對應(yīng)的表自增主鍵值

}

Spring利用這一技術(shù),提供了一個可以返回新增記錄對應(yīng)主鍵值的方法:?int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)?,其中第二個參數(shù)類型org.springframework.jdbc.support.KeyHolder,它是一個回調(diào)接口,Spring使用它保存新增記錄對應(yīng)的主鍵,該接口的接口方法描述如下:

Number getKey() throws InvalidDataAccessApiUsageException;

當(dāng)僅插入一行數(shù)據(jù),主鍵不是復(fù)合鍵且是數(shù)字類型時,通過該方法可以直接返回新的主鍵值。如果是復(fù)合主鍵,或者有多個主鍵返回時,該方法拋出 InvalidDataAccessApiUsageException。該方法是最常用的方法,因?yàn)橐话闱闆r下,我們一次僅插入一條數(shù)據(jù)并且主鍵字段類型為數(shù)字類型;

如果是復(fù)合主鍵,則列名和列值構(gòu)成Map中的一個Entry。如果返回的是多個主鍵,則拋出InvalidDataAccessApiUsageException異常;

Map getKeys() throws InvalidDataAccessApiUsageException;

如果返回多個主鍵,即PreparedStatement新增了多條記錄,則每一個主鍵對應(yīng)一個Map,多個Map構(gòu)成一個List。

List getKeyList():

Spring為KeyHolder接口指代了一個通用的實(shí)現(xiàn)類GeneratedKeyHolder,該類返回新增記錄時的自增長主鍵值。假設(shè)我們希望在新增論壇板塊對象后,希望將主鍵值加載到對象中,則可以按以下代碼進(jìn)行調(diào)整:

public voidaddForum(final Forum forum) {

final String sql = "INSERT INTO t_forum(forum_name,forum_desc) VALUES(?,?)";

KeyHolder keyHolder = newGeneratedKeyHolder(); // ①創(chuàng)建一個主鍵執(zhí)有者

getJdbcTemplate().update(newPreparedStatementCreator() {

public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {

PreparedStatement ps = conn.prepareStatement(sql);

ps.setString(1, forum.getForumName());

ps.setString(2, forum.getForumDesc());

returnps;

}

}, keyHolder);

forum.setForumId(keyHolder.getKey().intValue()); // ②從主鍵執(zhí)有者中獲取主鍵

}

這樣,在調(diào)用addForum(Forum forum)新增forum領(lǐng)域?qū)ο蠛?#xff0c;forum將擁有對應(yīng)的主鍵值,方便后繼的使用。在JDBC 3.0之前的版本中,PreparedStatement不能綁定主鍵,如果采用表自增鍵(如MySQL的auto increment或SQLServer的identity)將給獲取正確的主鍵值帶來挑戰(zhàn)——因?yàn)槟惚仨氃诓迦霐?shù)據(jù)后,馬上執(zhí)行另一條獲取新增主鍵的查詢語句。下面給出了不同數(shù)據(jù)庫獲取最新自增主鍵值的查詢語句:

posted on 2011-09-25 14:27 jadmin 閱讀(902) 評論(0) ?編輯 ?收藏

總結(jié)

以上是生活随笔為你收集整理的java 并发 主键_高并发数据库自增主键分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。