1.在最近的一次面试中,被问到你如何去实现一个事务。
当时我的回答是类似数据库日志的事务,将当前状态(undo文件)做一份拷贝即(redo文件),然后在拷贝(redo)上进行修改,若成功则用redo替换undo,若失败即进行回滚,使用undo文件,舍弃redo。
2.接着他又问了多库之间的事务实现。
这里我参照了2PC说了一下,即使用一个transitionManager作为中间件,在发起事务时,transitionManager通知所有事务进行预提交,然后所有事务进行反馈,若有一个事务反馈为NO,即向所有事务发送回滚请求,若接受全为YES,即进行提交。
后来仔细想想,其实在做设计方面更多应该去考虑的是他的原理,即抽象定义。
如何实现事务应该是由事务的特性决定的。这里事务有4大特性ACID;
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
一致性个人觉得更多的是数据的有效性和正确性。在分布式事务中,由于cap理论我们经常会舍弃强一致性,而实现最终一致性。即存在中间的软状态(base理论)。这里在分布式事务中,我们经常是先冻结金额,等待支付,真正扣除金额(或者解冻金额)。在等待支付阶段,其实他的数据在整体上说是不一致的,即不在正确状态,因为我们这边扣了金额,对方那边却还没到账,直到对方到账了,或者金额退还了,那么数据才是正确有效的,即真正的一致性。(以上纯属个人理解)
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
隔离性就要引出事务的4个隔离级别了:Read uncommitted,Read committed,Repeatable read,Serializable
这里给个链接大家去参考一下:事务的4种隔离级别
持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
在了解完事务的特性之后,我们设计事务就需要从事务的特性着手:
1.原子性
目前JAVA中我所知道能实现原子性的方式有2种:1.锁 、2cas
即在事务业务处理时,需要加锁或者使用cas操作保证该段业务保持原子性。
2一致性
在事务正常运行的情况下,用良好的原子性以及选用正确的事务隔离级别能保证数据的一致性。
若事务出现异常的情况,那就需要对数据进行校验操作,即在启动事务时进行备份,事务运行到一半宕机之后再重新启动,对现在的事务进行校验,若事务是处在已经正在提交阶段,就将数据全部回滚到事务开启前状态,重新进行提交。
3隔离性
事务的隔离性,其实就是通过不同的锁方式去实现。因为是用的不同锁,所以就会存在各种脏读,幻读和不可重复读等问题。
根据不同的业务方式,使用不同的隔离性。
4.持久性
即在机器宕机的情况下也能将数据恢复。写入文件,或者保存到数据库。
刚开始研究事务,有很多不懂之处,肯定有很多有错的地方,感谢大神过来指教啊!
网友评论