现有数据库开发过程中对事务的控制、事务锁、行锁、表锁的发现缺乏必要的方法和手段,通过以下手段可以丰富我们处理开发过程中处理锁问题的方法。For Update和For Update of使用户能够锁定指定表或表的数据行这个功能在实际应用中具有很重要的意义,特别对于多用户多线程处理中如要先获取数据通过判断在去更新数据(这中间不允许数据发生变化)的时候这个SQL功能是唯一最佳的选择。

  此外,为了解决因为For Update而引起的死锁问题,Oracle提供了select...[for update [of tab.col]] [nowait]功能,这个功能使得在执行select...for update前先检查所申请的行、表资源是否可用,如果可用则加写锁,否则直接返回Ora-54错误。这个功能也用很好的应用价值,在多线程中判断资源的可用性方面将发挥作用。

Table For Update For Update of A.Id
A 1.有where条件时,锁定条件中指定的数据行(行级封锁);
2.无where条件是,锁定表A(表级封锁)。
1.有where条件时,锁定条件中指定的数据行(行级封锁);
2.无where条件是,锁定表A(表级封锁)。
A,B 直接封锁A,B表(表级封锁) 1.有where条件时,封锁where条件中满足条件的A表的数据行(行级封锁),B表不锁定;
2.无where条件是,锁定A表(表级锁),B表不锁定。

通过对比发现,发现对于单表来说For Update和For Update of效果一样,只有在多表查询时产生差异,这个差异在于For Update of使用户能够锁定多表中的指定表或表的数据行。

  以代码为例:背景:有4台线上任务服务器,处理同一个表中的数据,为了避免引起数据读写混乱,采用了for update的方式来加锁。

@SuppressWarnings("unchecked")
public List<BizExpressDailyDO> fetchSomeBizExpressDaily(final String serverIp, final int some)
throws DataAccessException {
return (List<BizExpressDailyDO>) new TransactionTemplate(transactionManager).execute(new TransactionCallback() { @SuppressWarnings("rawtypes")
public Object doInTransaction(TransactionStatus status) {
// 取得锁的钥匙
getSqlMapClientTemplate().queryForObject("MS-SELECT-ACTION-LOCK-BY-LOCK-NAME-FOR-UPDATE", "bizexpress"); List<BizExpressDailyDO> bizexpresses = getSqlMapClientTemplate().queryForList(
"MS-FIND-SOME-BIZ-EXPRESS",
Integer.valueOf(some)); Map param = new HashMap();
param.put("serverIp", serverIp);
param.put("some", Integer.valueOf(some));
getSqlMapClientTemplate().update("MS-UPDATE-SOME-BIZ-EXPRESS", param); return bizexpresses;
}
});
}
上面中的MS-SELECT-ACTION-LOCK-BY-LOCK-NAME-FOR-UPDATE,
<!-- 锁定某个ACTION的纪录 -->
<select id="MS-SELECT-ACTION-LOCK-BY-LOCK-NAME-FOR-UPDATE" parameterClass="java.lang.String">
<![CDATA[
SELECT * FROM ACTION_LOCK WHERE LOCK_NAME = #value# FOR UPDATE
]]>
</select>

  通这这段代码对表加锁,这样其它线程当执行到此处时会处于等待状态,直到表锁释放,这样可以限制其它线程访问biz_express_daily表执行下面sql语句。

<!-- 挑选出一些纪录等待更新 -->
<select id="MS-FIND-SOME-BIZ-EXPRESS" resultMap="RM-BIZ-EXPRESS-DAILY">
<![CDATA[
SELECT * FROM BIZ_EXPRESS_DAILY WHERE SERVER_IP = '0.0.0.0' AND ROWNUM < #some#
]]>
</select>
<!-- 更新一些纪录的server_ip -->
<update id="MS-UPDATE-SOME-BIZ-EXPRESS">
<![CDATA[
UPDATE BIZ_EXPRESS_DAILY SET SERVER_IP = #serverIp#, GMT_MODIFIED = SYSDATE WHERE SERVER_IP = '0.0.0.0' AND ROWNUM < #some#
]]>
</update>

从而有效的解决了多线程并发数据库表的问题。

多线程并发同一个表问题(li)的更多相关文章

  1. 编写Java程序,实现多线程操作同一个实例变量的操作会引发多线程并发的安全问题。

    查看本章节 查看作业目录 需求说明: 多线程操作同一个实例变量的操作会引发多线程并发的安全问题.现有 3 个线程代表 3 只猴子,对类中的一个整型变量 count(代表花的总数,共 20 朵花)进行操 ...

  2. Java面试题整理一(侧重多线程并发)

    1..是否可以在static环境中访问非static变量? 答:static变量在Java中是属于类的,它在所有的实例中的值是一样的.当类被Java虚拟机载入的时候,会对static变量进行初始化.如 ...

  3. HashMap多线程并发问题分析

    转载: HashMap多线程并发问题分析 并发问题的症状 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题. ...

  4. HashMap多线程并发问题分析-正常和异常的rehash1(阿里)

    多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变 ...

  5. Java并发编程(03):多线程并发访问,同步控制

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发问题 多线程学习的时候,要面对的第一个复杂问题就是,并发模式下变量的访问,如果不理清楚内在流程和原因,经常会出现这样一个问题:线程处理 ...

  6. Java多线程并发编程/锁的理解

    一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等 ...

  7. Java 多线程 | 并发知识问答总结

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  8. Java多线程-并发容器

    Java多线程-并发容器 在Java1.5之后,通过几个并发容器类来改进同步容器类,同步容器类是通过将容器的状态串行访问,从而实现它们的线程安全的,这样做会消弱了并发性,当多个线程并发的竞争容器锁的时 ...

  9. 用读写锁三句代码解决多线程并发写入文件 z

    C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...

随机推荐

  1. 多线程 异步 beginInvoke EndInvoke 使用

    有许多耗时操作时,还要响应用户操作.这时候就需要用其他线程或者异步来搞.本来是改造公司的日志组件.因为多上了个国外大区的业务到来本系统来.这个系统其他地方都好就是日志,动不动就要死给我们看.有时候寻找 ...

  2. 学习C的笔记

    [unsigned] 16位系统中一个int能存储的数据的范围为-32768~32767,而unsigned能存储的数据范围则是0~65535.由于在计算机中,整数是以补码形式存放的.根据最高位的不同 ...

  3. SMBus set up a 2-byte EEPROM address for read/write

    Sequencer Engine spec: http://www.analog.com/media/en/technical-documentation/data-sheets/ADM1260.pd ...

  4. 将MPM雪模拟移植到Maya

    同事实现了一个迪士尼的MPM雪模拟论文,我将其移植到Maya中 论文题目是 A material point method for snow simulation 代码在这里: https://git ...

  5. XSS 前端防火墙 —— 天衣无缝的防护

    上一篇讲解了钩子程序的攻防实战,并实现了一套对框架页的监控方案,将防护作用到所有子页面. 到目前为止,我们防护的深度已经差不多,但广度还有所欠缺. 例如,我们的属性钩子只考虑了 setAttribut ...

  6. [Xamarin] 透過Native Code呼叫 JavaScript function (转帖)

    今天我們來聊聊關於如何使用WebView 中的Javascript 來呼叫 Native Code 的部分 首先,你得先來看看這篇[Xamarin] 使用Webview 來做APP因為這篇文章至少講解 ...

  7. Angular2学习笔记——在子组件中拿到路由参数

    工作中碰到的问题,特此记录一下. Angular2中允许我们以`path\:id\childPath`的形式来定义路由,比如: export const appRoutes: RouterConfig ...

  8. Nodejs之MEAN栈开发(七)---- 用Angular创建单页应用(下)

    上一节我们走通了基本的SPA基础结构,这一节会更彻底的将后端的视图.路由.控制器全部移到前端.篇幅比较长,主要分页面改造.使用AngularUI两大部分以及一些优化路由.使用Angular的其他指令的 ...

  9. 谈谈 Lock

    上来先看MSDN关于lock的叙述: lock  关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁.  下面的示例包含一个 lock 语句. lock  关键字可确保当一 ...

  10. .net垃圾回收机制编程调试试验

    1. 什么是CLR GC? 它是一个基于引用跟踪和代的垃圾回收器. 从本质上,它为系统中所有活跃对象都实现了一种引用跟踪模式,如果一个对象没有任何引用指向它,那么这个对象就被认为是垃圾对象,并且可以被 ...