MySQL foundation of affairs programming study notes

MySQL foundation of affairs programming study notes

In the study "MySQL Technology Insider: SQL Programming," a book, and took notes. This blog is content himself learned "MySQL Technology Insider: SQL Programming" Programming a chapter after the transaction, according to their own understanding of doing notes, content, and books are not the same, but the books through their own experiments verified, based on MySQL5.7 version. Notes aim is to facilitate their review, while sharing out maybe perhaps a little help others

1. Transaction Overview

A transaction is an important feature of the database is different from the file system, mentioned affairs will certainly think of four properties Affairs ACID, to ensure the normal use of the services, must ensure ACID, ACID represents atomicity (atomicity), consistency (consistency) , isolation (isolation), persistent (Durability), a good running transaction system is also required to have these characteristics

  • Atomicity (atomicity): a transaction must be regarded as an integral part of the smallest unit of work, all the operations of the entire transaction either all submitted successfully, or all fail rolled back, only part of the operation can not be performed

  • Consistency (consistency): the consistency of the database is always required from the state in a consistent state further converted to a consistency, such as bank transfers example, a reduction in the user account transfer 200, the other must be increased account receivables , a failure data must all roll back the state, to ensure transactional consistency

  • Isolation (isolation): In general, a firm made changes before submitting it for other transactions is not visible

  • Persistence (durability): Affairs once submitted, will be made permanent status stored in the database, even if the system Ben collapse, the modified data will not be lost

2, business classifieds

"MySQL Technology Insider: SQL Programming," a book mentioned the classification of the transaction, which introduced the classification of the transaction, from a theoretical point of view, the transaction is divided into:

  • Transaction flat (flat transactions)
  • Transaction savepoint with the flat (flat transactions with savepoints)
  • Chain Affairs (chained transactions)
  • Nested transactions (nested transactions)
  • Distributed Transactions (distributed transactions)
    flat transactions , this transaction is the most basic, the most simplest transaction, which is characterized by all operations are in the same level, all operations are in begin work and commit work (or rollback work between), having atomic transaction, the transaction is not flat but commit or rollback transactions a certain part, or several parts submitted transaction as originally filed with the flat or rolled back with
    the flat of the transaction with a savepoint because of the limitations of a flat transaction can not support the part of the transaction is rolled back, so there will be a save point with a flat transaction, such a transaction savepoint command can save a save point, you need to rollback time, use the command ROLLBACK TO SAVEPOINT identifier;should be noted that this transaction savepoints are not persistent, rollback to savepoint id does not mean that after the transaction has really roll back, you need to perform rollback work or commit work has truly commit the transaction
    chain transactions , described earlier, the flat transaction with a saving point save point does not have the durability of transactions, if Ben collapse of the system in the situation Condition, that the data did not save? Can not be rolled back to the nearest save point, so there is the emergence of the transaction chain, chain transactions do happen collapse of the system ran, rolled back to the nearest save point, of course, is not turned on by default in the mysql system, chain transaction role is to commit a transaction, releasing a data object, the implicit context necessary to pass a transaction begins, i.e. the commit transaction operation and start of the next transaction operations into an atomic operation , illustrated reference book:
    Here Insert Picture Description

Here Insert Picture Description
Although the case of chain transactions to avoid system collapse of Ben, data loss, but does not support the chain transaction is rolled back to save the specified point, can only roll back data to a transaction, but could do with a transaction savepoint rollback to specify the save point

嵌套事务,嵌套事务从名称就可以理解,这种一种层次结构的嵌套事务,有一个顶级事务(top-level transaction)控制着各个子事务(subtransaction),这种子事务可以是扁平事务、带保存点的扁平事务、链事务等等
Here Insert Picture Description
引用书中的嵌套式事务特征
Here Insert Picture Description
可以归纳重点,这种嵌套事务其实可以理解为一种树形结构,分为顶级事务,子事务,整个事务需要顶级事务提交后才真正算提交,任何一个子事务回滚都会导致所有子事务一起回滚,所有说整个嵌套事务具有原子性、一致性、隔离性,但是不具有事务持久性

分布式事务,分布式很容易理解,这种是在分布式环境运行的事务,一般也是扁平事务,不过是分布式环境的

3、事务控制语句

有了前面的理解之后,就可以学习事务的控制语句了,实践之后就可以更好地理解前面的理论知识

mysql默认事务是自动提交的,不过是可以通过命令进行关闭,也可以使用事务控制语句开启一个事务,所以,归纳一下,方法有二

## 方法1:通过set autocommit = 0关闭事务自动提交
# 查询是否开启事务自动提交,1:事务自动提交;2:事务不自动提交
SELECT @@autocommit;
# 关闭事务自动提交
SET autocommit = 0;
## 方法2:通过BEGIN 或者 START TRANSACTION命令
# 开启一个事务,使用这个命令之后,事务要使用commit或者commit work命令才会提交
BEGIN;
# START TRANSACTION命令和Begin命令效果一样 
START TRANSACTION;

事务控制语句语法:

  • BEGIN; / START TRANSACTION;
    这两个命令效果一样,都是用于开启事务
  • COMMIT WORK; / COMMIT;
    Commit和Commit work在默认情况效果是一样的,在链事务里就不一样,Commit还是执行Commit操作,Commit work在链事务里是执行Commit和开启另外一个新的事务,相当于commit+ BEGIN / START TRANSACTION,这两个操作是原子操作
  • ROLLBACK WORK;/ ROLLBACK;
    ROLLBACK和ROLLBACK WORK效果是一样的,都是回滚事务
  • SAVEPOINT identifier(保存点id命名);
    SAVEPOINT命令用于使用保存点,也就是前面介绍的带保存点的事务
    eg:savepoint tp1
  • RELEASE SAVEPOINT identifier;
    这个命令用于删除保存点
  • ROLLBACK TO SAVEPOINT identifier;
    这个命令用于回滚到对应的保存点

Mysql completion_type介绍:

# 查询completion_type类型
SHOW VARIABLES LIKE 'completion_type';
# 也可以使用@@系统变量方式查询
SELECT @@completion_type;
## completion_type默认值为0,它还有1和2两种值,不过在新版mysql5.7测试,发现值为2的情况不起效
SET @@completion_type = 1;# commit+chain(链事务,提示事务之后还会start transaction)
SET @@completion_type = 2;# commit+release(经过测试,在新版mysql5.7这个设置不起效,以前版本开启之后是会关闭Session的)

下面举例实验:

# 新建一个测试表
CREATE TABLE t (a INT,PRIMARY KEY(a))ENGINE = INNODB;
# 开启链事务
SET @@completion_type = 1;
# 开启一个事务,如下两个命令皆可
BEGIN; START TRANSACTION;
# 新增一条数据
INSERT INTO t SELECT 1;
# commit work在@@completion_type = 1的情况相关于commit+start transaction
COMMIT WORK;
# 新增一条数据
INSERT INTO t SELECT 2;
# 新增一条重复数据,让数据库报错
INSERT INTO t SELECT 2;
# 查询,有两条数据
SELECT * FROM t;
# 回滚事务
ROLLBACK;
# 再次查询,发现只有1这条数据,由此说明COMMIT WORK在commit之后,还开启了一个事务,当然是在autocommit值为1的情况进行验证的
SELECT * FROM t;

# completion_type=2在旧版估计才有用,我在5.7版本验证,发现并不起作用
SET @@completion_type=2;
# 开启事务
BEGIN;
# 新增一条数据
INSERT INTO t SELECT 1;
# commit work相关于commit+release,这个操作会关闭session
COMMIT WORK;
# 使用@@version验证会话是否关闭
SELECT @@version;

书中mysql版本是5.1,commit work之后是会关闭会话的,不过在5.7还是可以查询的,5.1版本报错引用书中图片
Here Insert Picture Description

4、事务隔离级别

SQL标准中定义四种隔离级别,每种存储引擎实现的隔离级别是不同的

  • READ UNCOMMITTED(未提交读)
    在READ UNCOMMITTED级别,事务即使没提交,对其它事务也是可见,允许事务读取未提交的数据,这也被称为脏读(Dirty Read),所以在实际生产中很少用

  • READ COMMIT(提交读)
    大部分数据库系统的默认隔离级别都是READ COMMIT,很明显这种隔离级别只能读取到已经提交事务的数据

  • REPEATABLE READ(可重复读)
    REPEATABLE READ可以解决脏读的问题,不过不能解决幻读问题,所谓幻读是指,在读取某个范围数据时候,另外一个事务又向这个范围写数据了,当之前事务再次读取这个范围数据时候就会产生幻读

  • SERIALIZABLE(可串行化)
    SERIALIZABLE是最高的隔离级别,SERIALIZABLE强制事务串行执行,可以避免幻读问题,其实保证SERIALIZABLE是常用行锁的方式来保证一致性的,SERIALIZABLE会在每一行的数据上都加上锁,SERIALIZABLE虽然可以保证事务安全性,不过服务器性能不好也会导致锁争用问题

查看当前会话隔离级别

SELECT @@tx_isolation;

查看系统全局隔离级别

SELECT @@global.tx_isolation;

设置当前会话隔离级别:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

设置mysql系统全局隔离级别:

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

5、分布式事务

MySQL中的分布式事务是通过XA事务事项的,当然要支持事务的存储引擎才可以,比如InnoDB,MySQL5.7版本,大部分存储引擎比如MyISAM,都是不支持事务的,也显然不支持XA事务,存储引擎不熟悉可以参考我之前博客:MySQL架构之逻辑架构简介

提到分布式事务,比较常见的就是银行转账的例子,对于银行银行转账这种场景就肯定要保证事务一致性,引用《MySQL技术内幕:SQL编程》书中例子,上海用户david向北京用户mariah的存储卡转账1000元,转账过程和到账过程肯定是分开的,首先上海银行的数据库先执行账号金额update操作,接着北京银行的数据库再执行账号金额update,假如没有保证事务一致性,上海银行数据库执行了,事务提交了,然后北京用户数据库没进行事务提交,这种情况是不允许的,所以就要保证事务一致性

在数据库层面可以使用mysql的XA事务,xa事务可以支持多种数据库,xa事务由一个或多个资源管理器(resource manager)、一个事务管理器(transaction manager)以及一个应用程序组成(application program)

  • 应用程序:定义事务的边界,指定全局事务中的操作
  • 资源管理器:提供访问事务资源的方法,通常一个数据库就是一个资源管理器
  • Organizer: Coordinating a global transaction needs and to participate in the global transaction resource manager communicates
    Quote: icon "MySQL Inside SQL Programming," a book:
    Here Insert Picture Description
    XA basic usage can refer to the official MySQL documentation , copied from the official website of xa usage :
XA {START|BEGIN} xid [JOIN|RESUME]

XA END xid [SUSPEND [FOR MIGRATE]]

XA PREPARE xid

XA COMMIT xid [ONE PHASE]

XA ROLLBACK xid

XA RECOVER [CONVERT XID]

Stand-alone environment XA Distributed example:

mysql>XA START 'a';
mysql>INSERT INTO t SELECT 1;
mysql>XA END 'a';
mysql>XA PREPARE 'a';
mysql>XA RECOVER;
mysql>XA COMMIT 'a';

Of course XA transactions must be used in a distributed environment, so the above examples are only exercises to familiarize yourself with the basic commands, examples in the book references in practice, use of the JDK JTA distributed transaction implementation

Built table:

create table t (username varchar(20),money float)engine=innodb;
insert into t(username,money) values('david',40000);
insert into t(username,money) values('jack',40000);

As for distributed transactions, is generally achieved through the application layer development language, JDK, there is provided JTA (JAVA Transaction API), code examples:


import javax.transaction.xa.Xid;

public class JTAXid implements Xid {
    private int formatId;
    private byte gtrid[];
    private byte bqual[];

    public JTAXid(){}

    public JTAXid(int formatId, byte gtrid[], byte bqual[]){
        this.formatId = formatId;
        this.gtrid = gtrid;
        this.bqual = bqual;
    }

    @Override
    public int getFormatId() {
        return formatId;
    }

    @Override
    public byte[] getGlobalTransactionId() {
        return gtrid;
    }

    @Override
    public byte[] getBranchQualifier() {
        return bqual;
    }
}

import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;

import javax.sql.XAConnection;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class JTADemo {
    //数据源设置
    public static MysqlXADataSource getDataSource(String connString,String user,String pwd){
        try{
            MysqlXADataSource dataSource = new MysqlXADataSource();
            dataSource.setUrl(connString);
            dataSource.setUser(user);
            dataSource.setPassword(pwd);
            return dataSource;
        }catch (Exception e){
            e.fillInStackTrace();
            return null;
        }
    }

    public static void main(String[] args){
        String connStr1 = "jdbc:mysql://192.168.0.11:3306/bank_shanghai";
        String connStr2 = "jdbc:mysql://192.168.0.12:3306/bank_beijing";
        XAResource xaResource1=null,xaResource2=null;
        Statement statement1 =null,statement2 =null;
        try {
            MysqlXADataSource dataSource1 = getDataSource(connStr1, "root", "zaq12wsx");
            XAConnection xaConnection1 = dataSource1.getXAConnection();
            xaResource1 = xaConnection1.getXAResource();
            Connection connection1 = xaConnection1.getConnection();
            statement1 = connection1.createStatement();

            MysqlXADataSource dataSource2 = getDataSource(connStr2, "root", "zaq12wsx");
            XAConnection xaConnection2 = dataSource2.getXAConnection();
            xaResource2 = xaConnection2.getXAResource();
            Connection connection2 = xaConnection2.getConnection();
            statement2 = connection2.createStatement();
        }catch (SQLException e){
            e.printStackTrace();
        }

        try{

            Xid xid1 = new JTAXid(101,new byte[]{0x01},new byte[]{0x02});
            Xid xid2 = new JTAXid(101,new byte[]{0x11},new byte[]{0x12});

            xaResource1.start(xid1, XAResource.TMNOFLAGS);
            statement1.execute("update t set money = money-1000 where user='david'");
            xaResource1.end(xid1, XAResource.TMSUCCESS);

            xaResource2.start(xid2, XAResource.TMNOFLAGS);
            statement2.execute("update t set money = money+1000 where user='jack'");
            xaResource2.end(xid2, XAResource.TMSUCCESS);

            int ret1 = xaResource1.prepare(xid1);
            int ret2 = xaResource2.prepare(xid2);
            //两个操作都正常运行才提交事务
            if (ret1 == XAResource.XA_OK && ret2 == XAResource.XA_OK) {
                xaResource1.commit(xid1, false);
                xaResource2.commit(xid2, false);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The contents of this blog, I read is: after "MySQL Inside SQL Programming", all the examples have been their own experiments, and then the book again summarized the content of their contents and the contents of the book is clearly relatively large difference, because he can understand knowledge transcripts, do not understand this blog records, readers need books to learn on their own, "MySQL technology insider: SQL programming," a book written in Chinese mysql is a master of classic books, examples and examples in the book are very online blog difficult to search, I admire the author's profound created, after I learn, although only a few to understand, but also feel benefit

Guess you like

Origin www.cnblogs.com/mzq123/p/12128607.html