高階特性—資料庫鎖定操作
資料庫是一個多用戶使用的共享資源,當多個使用者並發地存取資料時,在資料庫中就會產生多個交易同時存取相同資料的情況,若對並發操作不加以控制可能會造成資料的錯誤讀取和存儲,破壞資料庫的資料一致性,所以說,加鎖是實現資料庫並發控制的一個非常重要的技術;
資料庫加鎖的流程是:當事務在對某個資料物件進行操作前,先向系統發出請求對其加鎖,加鎖後的事務就對該資料物件有了一定的控制,在該事務釋放鎖之前,其他的事務無法對此資料物件進行更新操作;
因此,JDBC模組在資料庫查詢操作中整合了針對資料庫記錄鎖定的控制能力,稱之為IDBLocker,以參數的方式使用起來同樣的簡單!
首先了解IDBLocker提供的鎖定的類型:
MySQL:
IDBLocker.MYSQL:行級鎖,只有符合條件的資料被加鎖,其它進程等待資源解鎖後再進行操作;
#Oracle:
IDBLocker.ORACLE:行級鎖,只有符合條件的資料被加鎖,其它進程等待資源解鎖後再進行操作;
IDBLocker.ORACLE_NOWAIT:行級鎖,不進行資源等待,只要發現結果集中有些資料被加鎖,立刻返回「ORA-00054錯誤」;
SQL Server:
IDBLocker.SQLSERVER_NOLOCK:不加鎖,在讀取或修改資料時不加任何鎖;
IDBLocker.SQLSERVER_HOLDLOCK:保持鎖,將此共用鎖定保持至整個交易結束,而不會在途中釋放;
IDBLocker.SQLSERVER_UPDLOCK:修改鎖,能夠保證多個進程能同時讀取資料但只有該進程能修改資料;
IDBLocker.SQLSERVER_TABLOCK:表鎖,整個表設定共用鎖定直至該指令結束,確保其他行程只能讀取而不能修改資料;
IDBLocker.SQLSERVER_PAGLOCK:頁鎖;
IDBLocker.SQLSERVER_TABLOCKX:排它表鎖,將在整個表中設定排它鎖,能夠防止其他程序讀取或修改表中的資料;
其它資料庫:
可以透過IDBLocker介面自行實作;
session.find(EntitySQL.create(User.class) .field(Fields.create(User.FIELDS.ID, User.FIELDS.USER_NAME).excluded(true)) .forUpdate(IDBLocker.MYSQL));##範例程式碼二:透過Select查詢物件傳遞鎖定參數;
Select _select = Select.create(User.class, "u") .field("u", "username").field("ue", "money") .where(Where.create( Cond.create().eq(User.FIELDS.ID).param("bc19f5645aa9438089c5e9954e5f1ac5"))) .forUpdate(IDBLocker.MYSQL); session.find(SQL.create(_select), IResultSetHandler.ARRAY);
##
// User _user = new User(); _user.setId("bc19f5645aa9438089c5e9954e5f1ac5"); // _user.load(IDBLocker.MYSQL); // User _user = new User(); _user.setUsername("suninformation"); _user.setPwd(DigestUtils.md5Hex("123456")); // IResultSet<User> _users = _user.find(IDBLocker.MYSQL);
:請謹慎使用資料庫鎖定機制,盡量避免產生鎖定表,以免發生死鎖狀況!
#