并发控制 集群 分布式

并发事务的定义:多个事务同时发生,会产生5中并发问题(3个读,两个更新),但其实在数据库的某一个时刻,只会执行一个sql,但一个事务可能包含多个步骤(sql),这样可能多个事务的多个步骤交叉执行,而产生并发问题。


并发一般可以采取锁和隔离级别进行处理。
那锁和隔离级别的区别在于哪里:
隔离级别----解决看的问题--select
锁----解决更新的问题。
例如spring的事务就可以配置隔离级别,不同的隔离级别会影响事务在select时所查询的结果。
不过我们一般很少使用,一般使用数据库默认的隔离级别Read Committed,即只能查看已经提交的事务的数据。

锁一般可以分为:共享锁,独占锁。
按记录分又分为:表锁,行锁
我们在select时即取的是表的共享锁,那么独占锁,使用select ...for update实现
如果一个事务取得了独占锁,那么其他事务必须等待,等待那个事务提交后释放独占锁才能继续执行。

我们常见的锁解决方案如乐观锁:解决多个事务修改相同资源造成的不可重复读和第二类更新丢失。如hibernate的version 或timestamp

那么如果在如下场景,比如有golf场地,每个预订可以选择一个时间段,那么场地的可用要受时间的影响,在每次预订前,都要检查在该时间段是否有可用场地。在多线程情况下,控制这样[b]并发 insert[/b]乐观锁是做不到的,只能使用悲观锁,控制事务的并发。

如何使用悲观锁呢?
可以使用hibernate的Session 的Object load(Class theClass, Serializable id, LockOptions lockOptions);方法,新建一个T_LOCKS表,用来实现悲观锁,
XXXServiceImpl.java

lockDao.getLock();
//一系列dao操作
.......


hibernate的Query和Criteria都支持锁:

Criteria criteria = session.createCriteria(TLock.class);
criteria.add(Restrictions.eq("lockName", "facilitylock"));
criteria.setLockMode(LockMode.UPGRADE);
criteria.uniqueResult() ;

Query query = session.createQuery("from TLock where lockName= :lockName");
query.setParameter("lockName", "facilitylock");
query.setLockOptions(LockOptions.UPGRADE);
query.uniqueResult();

注意:select ...from tableName for update [color=red] 必须保证一定能查到记录,不然,不会有独占锁[/color]。因此,可以专门设计一张表t_locks用来存储各个需要使用独占锁的情况下去取对应的记录行的独占锁
个人感觉,数据库悲观锁类似于java的同步synchronized概念和作用,但在集群环境下java的synchronized不行,可以使用数据库悲观锁代替。

但是经使用发现mysql的并发处理性能在线程数到达100-200的时候明显降低,对于这种情况使用分布式锁,比如zookeeper是非常好的一个解决方案,zookeeper的应用场景之一就是分布式锁,而且性能经验证比mysql强很多。
分布式锁是同一进程内所有的线程共享的,所以分布式锁是用来控制集群环境中各节点的访问;
java的Synchronized是线程同步锁,只能允许一个进程的一个线程访问;

因此在分布是环境中,要控制同步,要加两个锁:一个是分布式锁,一个是线程锁(java 的Synchronize方法就可以)。

Curator是zoookeeper客户端框架,提供zookeeper的各种应用场景的封装API.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值