如何同时支持mysql和SQL_Mysql与sql语句

一、事务//1.事务的概念:事务是指逻辑上的一组操作,这组操作要么同时完成要么同时不完成。参考转账操作。

update account set money=money-100 where name=‘a’;

update account set money=money+100 where name=‘b’;//2.如果你自己不去控制事务,数据库默认一条sql语句就处在自己单独的事务当中。

//3.也可以使用命令去开启一个事务:

start transaction;--开启事务,这条语句之后的sql语句将处在一个事务当中,这些sql语句并不会立即执行

Commit--提交事务,一旦提交事务,事务中的所有sql语句才会执行。

Rollback--回滚事务,将之前所有的sql取消。

conn.setAutoCommit(false);

conn.commit();

conn.rollback();

conn.setSavePoint();

conn.rollback(sp);//4.事务的特性(ACID)

原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency):事务前后数据的完整性必须保持一致。在事务执行之前数据库是符合数据完整性约束的,

无论事务是否执行成功,事务结束后的数据库中的数据也应该是符合完整性约束的。

在某一时间点,如果数据库中的所有记录都能保证满足当前数据库中的所有约束,则可以

说当前的数据库是符合数据完整性约束的。

隔离性(Isolation): 事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所

干扰,多个并发事务之间数据要相互隔离。

持久性(Durability): 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数

据库发生故障也不应该对其有任何影响。//5.隔离性

将数据库设计为串行化程的数据库,让一张表在同一时间内只能有一个线程来操作。如果将数据库设计为这样,那数据库的

小率也太低了。所以数据库的设计这没有直接将数据库设计为串行化,而是为数据库提供多个隔离级别选项,使数据库的使

用者可以根据使用情况自己定义到底需要什么样的隔离级别。//不考虑隔离性可能出现的问题:

//脏读:一个事务读取到了另一个事务未提交的数据,这是特别危险的,要尽力防止。

a 1000b1000a:

start transaction;

update set money=money+100 where name=b;

b:

start transaction;

select* from account where name=b;--1100commit;

a:

rollback;

b:start transaction;

select* from account where name=b;--1000

//不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。(一个事务读取到了另一个事务已经提交的数据--

增加记录、删除记录、修改记录),在某写情况下并不是问题,在另一些情况下就是问题。

a:start transaction;

select 活期账户 from account where name=b;--1000 活期账户:1000select 定期账户 from account where name=b;--1000 定期账户:1000select 固定资产 from account where name=b;--1000 固定资产:1000

------------------------------b:

start transaction;

update set money=0 where name=b;

commit;------------------------------select 活期+定期+固定 from account where name=b; --2000 总资产: 2000

//虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一个事务读取到了另一个事务已经提交的数据---增加记录、删除记录),在某写情况下并不是问题,在另一些情况下就是问题。

b1000c2000d3000a:start transaction

select sum(money) from account;---3000 3000

-------------------d:start transaction;

insert into account values(d,3000);

commit;-------------------select count(*)from account;---3 3

3000/3 = 1000 1000

//四个隔离级别:

Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)

Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)不可以避免虚读

Read committed:可避免脏读情况发生(读已提交)

Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

安全性考虑:Serializable>Repeatable read>Read committed>Read uncommitted

数据库效率:Read uncommitted>Read committed>Repeatable read>Serializable

一般情况下,我们会使用Repeatable read、Read committed

mysql数据库默认的数据库隔离级别Repeatable read//mysql中设置数据库的隔离级别语句:

如何查询当前数据库的隔离级别?select @@tx_isolation;

如何设置当前数据库的隔离级别?set [global/session] transaction isolation level ...;

~此种方式设置的隔离级别只对当前连接起作用。

set transaction isolation level read uncommitted;

set session transaction isolation level read uncommitted;~此种方式设置的隔离级别是设置数据库默认的隔离级别

set global transaction isolation level read uncommitted;//8.数据库锁的机制:

共享锁:共享锁可以和共享锁共存,不能和排他锁共存。

排他锁:和任意锁都不共存。

mysql:

在非串行化的模式下,数据库在进行查询时不加任何锁。在进行修改记录时会加排他锁。

在串行话模式下,数据库在进行查询时加共享锁,在进行修改是加排他锁。

串行化是依赖锁来工作的。

死锁:如果两头互相等,mysql会自动帮我们停止一个事务,错误退出,而将另一个执行掉。

更新丢失:多线操作数据,在同一个查询结果的基础上进行修改,在进行提交,后提交的数据会将先提交的数据中的修改覆盖掉,造成更新数据丢失掉。

Serializable本身就能防止更新丢失问题。Serializable效率太低下。//9.更新丢失

如果多个线程操作,基于同一个查询结构对表中的记录进行修改,那么后修改的记录将会覆盖前面修改的记录,前面的修改就丢失

掉了,这就叫做更新丢失。

Serializable可以防止更新丢失问题的发生。其他的三个隔离级别都有可能发生更新丢失问题。

Serializable虽然可以防止更新丢失,但是效率太低,通常数据库不会用这个隔离级别,所以我们需要其他的机制来防止更新丢失://乐观锁和悲观锁不是数据库中真正存在的锁,只是人们在解决更新丢失时的不同的解决方案,体现的是人们看待事务的态度。

//悲观锁:

隔离级别不设置为Serializable,防止效率过低。

在查询时手动加上排他锁。

select* from table lock inshare mode(读锁、共享锁)

select* from table forupdate (写锁、排它锁)

如果数据库中的数据查询比较多而更新比较少的话,悲观锁将会导致效率低下。//乐观锁:

在表中增加一个version字段,在更新数据库记录是将version加一,从而在修改数据时通过检查版本号是否改变判断出当

前更新基于的查询是否已经是过时的版本。

如果数据库中数据的修改比较多,更新失败的次数会比较多,程序需要多次重复执行更新操作。//结论:

如果当前的这个表查询比较多而修改比较少,则应该使用乐观锁。

如果当前的这个表修改比较多而查询比较少,则应该使用悲观锁。

很多情况下,更新丢失根本就不是问题,所以在现实开发中往往不考虑此问题,只有在对数据要求非常严格的情况下要解决更新丢失。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值