没有开启事务的话直接提交、修改数据,有事务则进行两阶段提交:
①原子性
undolog 来实现一旦失败就马上触发回滚
当前事务是不可再分的,要么一起执行,要么都不执行。 start transaction
redolog日志池存储undolog日志,事务依次提交到undolog日志,undolog没有问题就一起commit数据(更改数据),有问题(其中任何一条)的话就不提交。
②持久性
事务一旦提交它对数据库的改变就是永久的
造成持久性危机的是因为两段式提交,我们不能因为数据库的故障(比如断电)就对数据的改变发生影响。
解决办法:在数据更改之前加上数据缓冲池(Buffer pool),undolog日志打印到缓冲池,数据端向缓冲池中进行定时刷脏来改变数据,如果错误被解决以后,那么数据就会改变(undolog日志有问题没有执行的话,sql语句将不会执行)。
例如断电之后,来电时日志中的东西会通过commit提交到数据库当中;
没有事务的话,语句会放到缓存池里,每隔一段时间提交一份数据到数据库中,一旦断电,数据就会丢失。
③隔离性
并发执行的事务是不会相互干扰的(A、B两个事务同时对数据库进行操作)
隔离性的隔离级别:(隔离级别越高,解决并发产生的问题越多)
1、读未提交 read uncommitted
2、读已提交 read committed
3、可重复读 repeatable read
4、串行化 serializable
事务的并发问题:
1、读未提交---脏读:事务A读取到了事务B修改但是还没有提交的数据。(读取到了undolog中刷脏前的数据)
读已提交解决了脏读的现象,但会造成不可重复读的现象
2、读已提交---不能重复读:事务A多次查询到的结果不一致。(事务A读取到了事务B提交后的数据,对于事务A来说读取数据在事务B提交之前和之后是不一样的)(Orcal)
可重复度解决了不能重复读的现象,但会造成幻读的现象
3、可重复度---幻读:当事务A要求全部查询表当中的数据,与此同时事务B对表进行了增删改操作,那么对于事务A来说,查询不到事务B的任何操作,就跟出现幻觉一样。(Mysql)
如何解决幻读?串行化
4、串行化---解决了上边的问题---> 让事务一个一个的执行(串行执行)。只有a提交之后b才能查询出来,等待提交过程中b一直都在等待。
(缺点:吞吐量太小)
mysql:设置的可重复读
oracal:设置的不可重复度
④一致性
(最后的保障,前面3个性质都是为了保证一致性)
事务结束时,数据库完整性不会得到破坏【转账总额不变】