首先锁表
在业务数据量不大的时候,可以通过锁表的方式来防止并发同时插入相同数据的问题
锁表后执行的方法就是排队执行,一次只允许一个方法调用,其余调用锁表后进行的方法都排队等待,等前一个执行完毕之后才能继续调用。(在这里我认为和synchronize起到的作用是一样的)。
同事提供给我的思路是如果使用synchronize不能更好的准确的去加这个关键字,远远不如照这样子对锁表去for update来的准确和快。
具体的实现方法是
public void test() throws Exception {
Map m=new HashMap<>();
m.put("type","test")
//在进方法就在进行锁表(根据传入的类型锁其中一行)
lockMapper.lock(m);
//开始执行业务逻辑
.....
}
lockMapper.class就省略了
lockMapper.xml
<select id="lock" resultType="java.lang.String" parameterType="map" >
select
1
from tableLock
where type = #{type,jdbcType=VARCHAR}
for update
</select>
建表语句是:
create table tableLock
(
type VARCHAR2(30) not null,
id VARCHAR2(10) not null
)
优点:这样可以避免这个方法的并发
缺点:当多个方法同时调用这个方法的时候效率会出现问题
这样属于在事务中:
人为的串行化
并发的一点知识可以在链接中看
https://www.cnblogs.com/zhu-wj/p/7067455.html
----------------------
事务外:
现在分布式的系统越来越多,但是再分布的系统也会有些共享资源,比如redis或zookeeper,可以利用redis或者zookeeper造一些分布式的锁(此类属于其他博文内容,在此不再展开)。利用事务外部的锁将同类型的事务做一些串行化处理,再配合事务内部的检查机制,足以确保解决事务的并发问题。