高級(jí)特性—數(shù)據(jù)庫(kù)鎖操作

2018-12-24 22:25 更新

數(shù)據(jù)庫(kù)是一個(gè)多用戶使用的共享資源,當(dāng)多個(gè)用戶并發(fā)地存取數(shù)據(jù)時(shí),在數(shù)據(jù)庫(kù)中就會(huì)產(chǎn)生多個(gè)事務(wù)同時(shí)存取同一數(shù)據(jù)的情況,若對(duì)并發(fā)操作不加以控制就可能會(huì)造成數(shù)據(jù)的錯(cuò)誤讀取和存儲(chǔ),破壞數(shù)據(jù)庫(kù)的數(shù)據(jù)一致性,所以說,加鎖是實(shí)現(xiàn)數(shù)據(jù)庫(kù)并發(fā)控制的一個(gè)非常重要的技術(shù);

數(shù)據(jù)庫(kù)加鎖的流程是:當(dāng)事務(wù)在對(duì)某個(gè)數(shù)據(jù)對(duì)象進(jìn)行操作前,先向系統(tǒng)發(fā)出請(qǐng)求對(duì)其加鎖,加鎖后的事務(wù)就對(duì)該數(shù)據(jù)對(duì)象有了一定的控制,在該事務(wù)釋放鎖之前,其他的事務(wù)不能對(duì)此數(shù)據(jù)對(duì)象進(jìn)行更新操作;

因此,JDBC模塊在數(shù)據(jù)庫(kù)查詢操作中集成了針對(duì)數(shù)據(jù)庫(kù)記錄鎖的控制能力,稱之為IDBLocker,以參數(shù)的方式使用起來同樣的簡(jiǎn)單!

首先了解一下IDBLocker提供的鎖的類型:

  • MySQL:

    IDBLocker.MYSQL:行級(jí)鎖,只有符合條件的數(shù)據(jù)被加鎖,其它進(jìn)程等待資源解鎖后再進(jìn)行操作;

  • Oracle:

    IDBLocker.ORACLE:行級(jí)鎖,只有符合條件的數(shù)據(jù)被加鎖,其它進(jìn)程等待資源解鎖后再進(jìn)行操作;

    IDBLocker.ORACLE_NOWAIT:行級(jí)鎖,不進(jìn)行資源等待,只要發(fā)現(xiàn)結(jié)果集中有些數(shù)據(jù)被加鎖,立刻返回“ORA-00054錯(cuò)誤”;

  • SQL Server:

    IDBLocker.SQLSERVER_NOLOCK:不加鎖,在讀取或修改數(shù)據(jù)時(shí)不加任何鎖;

    IDBLocker.SQLSERVER_HOLDLOCK:保持鎖,將此共享鎖保持至整個(gè)事務(wù)結(jié)束,而不會(huì)在途中釋放;

    IDBLocker.SQLSERVER_UPDLOCK:修改鎖,能夠保證多個(gè)進(jìn)程能同時(shí)讀取數(shù)據(jù)但只有該進(jìn)程能修改數(shù)據(jù);

    IDBLocker.SQLSERVER_TABLOCK:表鎖,整個(gè)表設(shè)置共享鎖直至該命令結(jié)束,保證其他進(jìn)程只能讀取而不能修改數(shù)據(jù);

    IDBLocker.SQLSERVER_PAGLOCK:頁(yè)鎖;

    IDBLocker.SQLSERVER_TABLOCKX:排它表鎖,將在整個(gè)表設(shè)置排它鎖,能夠防止其他進(jìn)程讀取或修改表中的數(shù)據(jù);

  • 其它數(shù)據(jù)庫(kù):

    可以通過IDBLocker接口自行實(shí)現(xiàn);

下面通過示例代碼展示如何使用鎖:

示例代碼一:通過EntitySQL對(duì)象傳遞鎖參數(shù);

session.find(EntitySQL.create(User.class)
        .field(Fields.create(User.FIELDS.ID, User.FIELDS.USER_NAME).excluded(true))
        .forUpdate(IDBLocker.MYSQL));

示例代碼二:通過Select查詢對(duì)象傳遞鎖參數(shù);

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);

示例代碼三:基于數(shù)據(jù)實(shí)體對(duì)象傳遞鎖參數(shù)

//
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);

注意

請(qǐng)謹(jǐn)慎使用數(shù)據(jù)庫(kù)鎖機(jī)制,盡量避免產(chǎn)生鎖表,以免發(fā)生死鎖情況!

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)