数据库之mysql与oracle比较
1. 比较
项目 | mysql | oracle |
---|---|---|
对事务的提交 | 自动提交 | 需要手动提交,commit |
事务隔离级别 | repeatable-read,可重复读 | read commit, 读已提交 |
对事务的支持 | 在innodb存储引擎的行级锁的情况下才可支持事务 | 完全支持事务 |
存储引擎 | Innodb(B+树),myISAM(B+树), memory | 无, B-树 |
应用场景 | 小巧,免费,安装简单。集中于互联网方向 | 收费,安全性高。 适用于服务器比较大的单节点或集群环境,对于可用性,安全性,健壮性,实时性要求极高的业务。大型企业,银行、金融 |
单表数据量 | 单表行数超过 500 万行或者单表容量超过 2GB,推荐进行分库分表 | 推荐是单表500万 |
备注:
事务隔离级别为读提交时,写数据只会锁住相应的行
事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
2. 行级锁
mysql行级锁:
mysql中的行级锁是由以下sql语句产生:
select * from job_info where id = 1 for update;
主要加上了for update,其中id为主键。
如果查询条件不是主键,则会成为表锁。
3. 悲观锁与乐观锁
悲观锁和乐观锁
悲观锁虽然能保证数据一致,可是如果进程从读取到更新的时间太长,会导致其他进程等待时间较长,使得系统效率降低。如有重试机制,也可能会耗光数据库连接数。
乐观锁,是为数据库表增加一个标识数据版本的version字段来实现的,读取数据时把version字段一同读出,写入数据库时比对version字段就知道数据是否被更改过,如果version不相等就说明持有的是过期数据,不能写入,如果相等就可以写入,并把version加一。
4. @Transactional注意点
4.1 不要在接口上声明@Transactional ,而要在具体类的方法上使用 @Transactional 注解,否则注解可能无效。
4.2 不要图省事,将@Transactional放置在类级的声明中,放在类声明,会使得所有方法都有事务。故@Transactional应该放在方法级别,不需要使用事务的方法,就不要放置事务,比如查询方法。否则对性能是有影响的。
4.3 使用了@Transactional的方法,对同一个类里面的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)
4.4 使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他类调用才有效,故只能是public。道理和上面的有关联。故在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也 不会报错,但事务无效。