现有数据库开发过程中对事务的控制、事务锁、行锁、表锁的发现缺乏必要的方法和手段,通过以下手段可以丰富我们处理开发过程中处理锁问题的方法。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. [数据结构]——链表(list)、队列(queue)和栈(stack)

    在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...

  2. “老坛泡新菜”:SOD MVVM框架,让WinForms焕发新春

    火热的MVVM框架 最近几年最热门的技术之一就是前端技术了,各种前端框架,前端标准和前端设计风格层出不穷,而在众多前端框架中具有MVC,MVVM功能的框架成为耀眼新星,比如GitHub关注度很高的Vu ...

  3. 计算Div标签内Checkbox个数或已被disabled的个数

    先看下面的html: 计算div内的checkbox个数:$('#divmod input[type="checkbox"]').length 计算div内checkbox被dis ...

  4. Git学习笔记一:新建本地仓库及初始化

    1.百度搜索Git下载安装,直接按默认选项安装即可. 例如:Git-2.7.2-32-bit_setup.1457942412.exe 2.配置Git信息,建立版本仓库 (Alt+PrintScerr ...

  5. 解决托管在Windows上的Stash的Pull request无法合并的问题

    最近尝试合并一个托管在Windows的Stash系统中的pull request时,发现合并按钮被禁用,显示有冲突不能合并,但是在diff页面中没有现实冲突,而且代码实际上并没有任何冲突. 后来在这篇 ...

  6. Windows10-UWP中设备序列显示不同XAML的三种方式[3]

    阅读目录: 概述 DeviceFamily-Type文件夹 DeviceFamily-Type扩展 InitializeComponent重载 结论 概述 Windows10-UWP(Universa ...

  7. useful Ansible commands

    This article includes some useful Ansible commands. I will try to write blogs by English. You may wa ...

  8. 一种简单,轻量,灵活的C#对象转Json对象的方案(续)

    本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...

  9. Android Secret Code

    我们很多人应该都做过这样的操作,打开拨号键盘输入*#*#4636#*#*等字符就会弹出一个界面显示手机相关的一些信息,这个功能在Android中被称为android secret code,除了这些系 ...

  10. Android点击列表后弹出输入框,所点击项自动滚动到输入框上方

    使用微信的朋友圈会发现,点击某一条评论后输入框会弹出来,然后所点击的那一项会自动地滚动到输入框上方的位置,这样如果开始所点击的评论在屏幕很下方的话,就不会被输入框遮住,虽然微信这一点在我的MX2频繁点 ...