(http://www.blogjava.net/i369/archive/2007/04/29/108906.html)

transaction在数据库编程中是一个重要的概念,这样做可以控制对数据库操作的事务提交。 但是要想在程序中实现事务,要求数据库本身支持事务。 现在的关系型数据库,我们日常使用的mysql,oracle等等都支持事务,有的是安装后直接就支持,有的需要做一些设置。 这篇文章是针对mysql的,讲述从数据库安装,设置,一直到sql语句,甚至到java程序中,如何实现transaction。 1.安装 要想在mysql的表中支持transaction,必须要求是innodb表。普通表使用的autocommit模式,会自动提交每一条sql语句,不能算是transaction吧。 安装时要指定mysql支持innodb,./configure --with-innodb。

2.配置 安装后,可以对innodb做一些配置,在my.cnf或my.ini中的[mysqld]段。 #存储目录,如果不指定默认为安装的data目录,为空时以innodb_data_file_path指定路径为准 innodb_data_home_dir = #数据文件名及大小,默认为ibdata1,10m大小。autoextend可以自增,max:2000M文件最大2g,因为有的硬盘有2g文件大小限制。 innodb_data_file_path = ibdata1:2000M;ibdata2:2000M:autoextend:max:2000M # 设置缓冲池大小 set-variable = innodb_buffer_pool_size=70M set-variable = innodb_additional_mem_pool_size=10M #设置日志文件路径,默认在date目录下,名称为ib_logfile... innodb_log_group_home_dir = #设置日志文件数目,默认为3 set-variable = innodb_log_files_in_group=3 # 设置日志文件大小 set-variable = innodb_log_file_size=10M # 设置日志缓冲大小 set-variable = innodb_log_buffer_size=8M # 任何事务提交前写入日志,方便故障诊断,请设为1。如果丢失最近的几个事务影响不大的话,设置为0(默认值)。 innodb_flush_log_at_trx_commit=1 #设置超时时间 set-variable = innodb_lock_wait_timeout=50

注意:innodb不会自动生成目录,上面所有指定目录要手工生成。默认不用。

完整的配置参数如下表(下表引自http://man.chinaunix.net/database/mysql/inonodb_zh/2.htm#InnoDB_start):

innodb_data_home_dir

这是InnoDB表的目录共用设置。如果没有在 my.cnf进行设置,InnoDB 将使用MySQL的 datadir目录为缺省目录。如果设定一个空字串,可以在 innodb_data_file_path中设定绝对路径。

innodb_data_file_path

单独指定数据文件的路径与大小。数据文件的完整路径由 innodb_data_home_dir 与这里所设定值的组合。 文件大小以 MB 单位指定。因此在文件大小指定后必有“M”。 InnoDB 也支持缩写“G”, 1G = 1024M。从 3.23.44 开始,在那些支持大文件的操作系统上可以设置数据文件大小大于 4 GB。而在另一些操作系统上数据文件必须小于 2 GB。数据文件大小总和至少要达到 10 MB。在 MySQL-3.23 中这个参数必须在 my.cnf中明确指定。在 MySQL-4.0.2 以及更新版本中则不需如此,系统会默认在 MySQL 的 datadir目录下创建一个 16 MB 自扩充(auto-extending)的数据文件 ibdata1。你同样可以使用一个 原生磁盘分区(RAW raw disk partitions(raw devices)) 作为数据文件, 如何在 my.cnf中详细指定它们请查看第 12.1 节。

innodb_mirrored_log_groups

为了保护数据而设置的日志文件组的拷贝数目,默认设置为 1。在 my.cnf中以数字格式设置。

innodb_log_group_home_dir

InnoDB 日志文件的路径。必须与 innodb_log_arch_dir设置相同值。 如果没有明确指定将默认在 MySQL 的 datadir目录下建立两个 5 MB 大小的 ib_logfile...文件。

innodb_log_files_in_group

日志组中的日志文件数目。InnoDB 以环型方式(circular fashion)写入文件。数值 3 被推荐使用。在 my.cnf中以数字格式设置。

innodb_log_file_size

日志组中的每个日志文件的大小(单位 MB)。如果 n 是日志组中日志文件的数目,那么理想的数值为 1M 至下面设置的缓冲池(buffer pool)大小的 1/n。较大的值,可以减少刷新缓冲池的次数,从而减少磁盘 I/O。但是大的日志文件意味着在崩溃时需要更长的时间来恢复数据。 日志文件总和必须小于 2 GB,3.23.55和 4.0.9 以上为小于 4 GB。在 my.cnf中以数字格式设置。

innodb_log_buffer_size

InnoDB 将日志写入日志磁盘文件前的缓冲大小。理想值为 1M 至 8M。大的日志缓冲允许事务运行时不需要将日志保存入磁盘而只到事务被提交(commit)。 因此,如果有大的事务处理,设置大的日志缓冲可以减少磁盘I/O。 在 my.cnf中以数字格式设置。

innodb_flush_log_at_trx_commit

通常设置为 1,意味着在事务提交前日志已被写入磁盘, 事务可以运行更长以及服务崩溃后的修复能力。如果你愿意减弱这个安全,或你运行的是比较小的事务处理,可以将它设置为 0 ,以减少写日志文件的磁盘 I/O。这个选项默认设置为 0。

innodb_log_arch_dir

The directory where fully written log files would be archived if we used log archiving. 这里设置的参数必须与 innodb_log_group_home_dir相同。 从 4.0.6 开始,可以忽略这个参数。

innodb_log_archive

这个值通常设为 0。 既然从备份中恢复(recovery)适合于 MySQL 使用它自己的 log files,因而通常不再需要 archive InnoDB log files。这个选项默认设置为 0。

innodb_buffer_pool_size

InnoDB 用来高速缓冲数据和索引内存缓冲大小。 更大的设置可以使访问数据时减少磁盘 I/O。在一个专用的数据库服务器上可以将它设置为物理内存的 80 %。 不要将它设置太大,因为物理内存的使用竞争可能会影响操作系统的页面调用。在 my.cnf中以数字格式设置。

innodb_additional_mem_pool_size

InnoDB 用来存储数据字典(data dictionary)信息和其它内部数据结构(internal data structures)的存储器组合(memory pool)大小。理想的值为 2M,如果有更多的表你就需要在这里重新分配。如果 InnoDB 用尽这个池中的所有内存,它将从操作系统中分配内存,并将错误信息写入 MySQL 的错误日志中。在 my.cnf中以数字格式设置。

innodb_file_io_threads

InnoDB 中的文件 I/O 线程。 通常设置为 4,但是在 Windows 下可以设定一个更大的值以提高磁盘 I/O。在 my.cnf中以数字格式设置。

innodb_lock_wait_timeout

在回滚(rooled back)之前,InnoDB 事务将等待超时的时间(单位 秒)。InnoDB 会自动检查自身在锁定表与事务回滚时的事务死锁。如果使用 LOCK TABLES命令,或在同一个事务中使用其它事务安全型表处理器(transaction safe table handlers than InnoDB),那么可能会发生一个 InnoDB 无法注意到的死锁。在这种情况下超时将用来解决这个问题。这个参数的默认值为 50 秒。在 my.cnf中以数字格式设置。

innodb_flush_method

这个参数仅仅与 Unix 相关。这个参数默认值为 fdatasync。 另一个设置项为 O_DSYNC。这仅仅影响日志文件的转储,在 Unix 下以 fsync转储数据。InnoDB 版本从 3.23.40b 开始,在 Unix 下指定 fdatasync为使用 fsync方式、指定 O_DSYNC为使用 O_SYNC方式。由于这在某些 Unix 环境下还有些问题所以在 'data' versions 并没有被使用。

innodb_force_recovery

警告:此参数只能在你希望从一个被损坏的数据库中转储(dump)数据的紧急情况下使用! 可能设置的值范围为 1 - 6。查看下面的章节 'Forcing recovery' 以了解这个参数的具体含义。参数设置大于 0 的值代表着 InnoDB 防止用户修改数据的安全度。从 3.23.44 开始,这个参数可用。在 my.cnf中以数字格式设置。

innodb_fast_shutdown

InnoDB 缺少在关闭之前清空插入缓冲。这个操作可能需要几分钟,在极端的情况下可以需要几个小时。如果这个参数据设置为 1 ,InnoDB 将跳过这个过程而直接关闭。从 3.23.44 和 4.0.1 开始,此参数可用。从 3.23.50 开始,此参数的默认值为 1。

innodb_thread_concurrency

InnoDB 会试图将 InnoDB 服务的使用的操作系统进程小于或等于这里所设定的数值。此参数默认值为 8。如果计算机系统性能较低或 innodb_monitor显示有很多线程等侍信号,应该将这个值设小一点。如果你的计算机系统有很我的处理器与磁盘系统,则可以将这个值设高一点以充分利用你的系统资源。建议设值为处理器数目+ 磁盘数目。 从 3.23.44 和 4.0.1 开始,此参数可用。在 my.cnf中以数字格式设置。

innodb还需要使用二进制日志文件:

log-bin指定二进制文件名称,不指定默认生成。 log-bin-index 可以指定索引文件。 使用 binlog-do-db可以指定记录的数据库。 使用 binlog-ignore-db可以指定不记录的数据库。 注意的是: binlog-do-db 和binlog-ignore-db 一次只指定一个数据库,指定多个数据库需要多个语句。而且,MySQL会将所有的数据库名称改成小写, 在指定数据库时必须全部使用小写名字,否则不会起作用。

3.添加表 CREATE TABLE user (id INT NOT NULL AUTO_INCREMENT,PRIMARY KEY,fname VARCHAR(15),sname VARCHAR(20),sex VARCHAR(6),age VARCHAR(3)) TYPE=INNODB; 记得后面的TYPE=INNODB。

4.sql语句的transaction实现 两种方式: 如果SET AUTOCOMMIT=0;也就是关闭了自动提交,那么任何commit或rallback语句都可以触发事务提交。 比如:  mysql> SET AUTOCOMMIT=0;  Query OK, 0 rows affected (0.00 sec)    mysql> INSERT INTO user(fname,sname) VALUES ('Max','Ma');  Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO user(fname,sname) VALUES ('Sky','Sun');  Query OK, 1 row affected (0.00 sec)    mysql> COMMIT;  Query OK, 0 rows affected (0.00 sec) 这样事务就算提交了。 如果SET AUTOCOMMIT=1;也就是开启了自动提交(默认值),那么必须要以begin或者START TRANSACTION声明事务的开始,然后再以commit或rallback语句都可以触发事务提交。 比如:  mysql> SET AUTOCOMMIT=1;  Query OK, 0 rows affected (0.00 sec)

mysql> BEGIN;  Query OK, 0 rows affected (0.00 sec)    mysql> INSERT INTO user(fname,sname) VALUES ('Max','Ma');  Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO user(fname,sname) VALUES ('Sky','Sun');  Query OK, 1 row affected (0.00 sec)    mysql> COMMIT;  Query OK, 0 rows affected (0.00 sec)

像其他关系型数据库一样,也可以使用存储过程(procedure)来封装事务。

5.java程序开发中的实现。 涉及到程序开发实现方法就多了。 一.自己写方法把mysql的底层transaction命令封装。我感觉程序开发中应该尽量避免和底层数据库的过多交互,我没有实现它。 有人实现了,下面是他实现的一个例子网址:http://dlog.cn/html/diary/showlog.vm?sid=7&log_id=2516 二.java的jdbc开发包包含了操作transaction的方法,在java.sql.connection接口里。 使用他的好处是可以和多种类型数据库交互。 三.hibernate等ORM框架工具。 hibernate 中也封状了对transaction的操作,在org.hibernate.Session类中,使用beginTransaction()方法开启 transaction;使用getTransaction().commit()提交transaction;使用getTransaction(). rollback()方法回滚transaciton。 四.这是我常用的一种方法,把hibernate的session的方法封装或者实现jdbc的connection的接口。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1481131

Mysql的transaction实现(转)的更多相关文章

  1. 19-04【mysql】transaction,autocommit

    本地使用mysql测试结果如下, 没有使用start transaction的情况下: 如果set autocommit=1,则每一条语句默认提交: 如果set autocommit=0,则这条语句默 ...

  2. MySQL——事务(transaction)简单总结

    简介: MySQL事务操作主要用于处理操作量大,复杂度高的数据,比如说,在人员管理系统中要删除一个人员,你既要删除他的基本资料,也要删除该人员的相关信息,如文章.信箱等.这些数据库操作语句就构成了一个 ...

  3. MySQL SET TRANSACTION 设置事务隔离级别

    1. 首先说一下autocommit 默认情况下autocommit的开关是打开的,也就是ON,查看方法 方法1. select @@[global/session].autocommit; 方法2. ...

  4. MySQL——事务(Transaction)详解

    原文:https://blog.csdn.net/w_linux/article/details/79666086

  5. MySQL Crash Course #18# Chapter 26. Managing Transaction Processing

    InnoDB 支持 transaction ,MyISAM 不支持. 索引: Changing the Default Commit Behavior SAVEPOINT 与 ROLLBACK TO ...

  6. MySQL 5.6 Reference Manual-14.3 InnoDB Transaction Model and Locking

    14.3 InnoDB Transaction Model and Locking 14.3.1 InnoDB Lock Modes 14.3.2 InnoDB Record, Gap, and Ne ...

  7. 再谈Transaction——MySQL事务处理分析

    MySQL 事务基础概念/Definition of Transaction 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个 sql 语句,这些语句要么都执行 ...

  8. MySQL 一致性读 深入研究

    一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/innod ...

  9. mysql timeout知多少

    1.timeout变量知多少 打开mysql,用show variables like '%timeout%'命令一看,不看不知道,一看吓一跳,结果如下面所示,这么多timeout相关变量,一下就吓尿 ...

随机推荐

  1. 洛谷P3674 小清新人渣的本愿(莫队)

    传送门 由乃tql…… 然后抄了一波zcy大佬的题解 我们考虑把询问给离线,用莫队做 然后用bitset维护,每一位代表每一个数字是否存在,记为$now1$ 然后再记录一个$now1$的反串$now2 ...

  2. FullCalendar插件的基本使用

    我的另一博客地址:https://segmentfault.com/u/lyrfighting/articles 前段时间,一直在开发考勤系统,当时为满足设计的需求,选了好几个插件,最后决定采用Ful ...

  3. [POI2009]KAM-Pebbles BZOJ1115 [ 待填坑 ] 博弈

    有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜. 感谢 ...

  4. zabbix监控java内存的脚本

    #!/bin/bash # 截取java的pid号 java_pid=`netstat -lnpt |grep |awk -F '/' '{print $1'}` # 截取$jstat命令的位置 js ...

  5. Luogu P4404 [JSOI2010]缓存交换 优先队列

    细节题?...调了半天.... 可以发现,每一次从缓存中删除的主存一定是下次访问最晚的,可以用优先队列来处理...还有要离散化...还有链表末尾要多建一些点...否则会死的很惨... #include ...

  6. Codeforces Round #482 (Div. 2) C 、 Kuro and Walking Route(dfs)979C

    题目链接:http://codeforces.com/contest/979/problem/C 大致题意 给出n个点,有n-1个边将他们链接.给出x,y,当某一路径中出现x....y时,此路不通.路 ...

  7. 磁盘 IO 和网络 IO 该如何评估、监控、性能定位和优化?

    生产中经常遇到一些IO延时长导致的系统吞吐量下降.响应时间慢等问题,例如交换机故障.网线老化导致的丢包重传:存储阵列条带宽度不足.缓存不足.QoS限制.RAID级别设置不当等引起的IO延时. 一.评估 ...

  8. PreparedStatement是如何防止SQL注入的?

    为什么在Java中PreparedStatement能够有效防止SQL注入?这可能是每个Java程序员思考过的问题. 首先我们来看下直观的现象(注:需要提前打开mysql的SQL文日志) 1. 不使用 ...

  9. 2048小游戏(Java)(swing实现)(二)

    这里是上一次的成果,只能用鼠标点,没法用键盘 最近扩充了一下知识面,实现了用键盘操控2048小游戏 但是还是不支持同时使用键盘和鼠标同时操作 import javax.swing.*; //impor ...

  10. my26_Slave failed to initialize relay log info structure from the repository

    重启了一下从库,忘记先stop slave ,直接mysqladmin shutdown关闭实例,结果起不来了 mysql> start slave;ERROR 1872 (HY000): Sl ...