空間站

          北極心空

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

          transaction在數(shù)據(jù)庫(kù)編程中是一個(gè)重要的概念,這樣做可以控制對(duì)數(shù)據(jù)庫(kù)操作的事務(wù)提交。
          但是要想在程序中實(shí)現(xiàn)事務(wù),要求數(shù)據(jù)庫(kù)本身支持事務(wù)。
          現(xiàn)在的關(guān)系型數(shù)據(jù)庫(kù),我們?nèi)粘J褂玫膍ysql,oracle等等都支持事務(wù),有的是安裝后直接就支持,有的需要做一些設(shè)置。
          這篇文章是針對(duì)mysql的,講述從數(shù)據(jù)庫(kù)安裝,設(shè)置,一直到sql語(yǔ)句,甚至到j(luò)ava程序中,如何實(shí)現(xiàn)transaction。
          1.安裝
          要想在mysql的表中支持transaction,必須要求是innodb表。普通表使用的autocommit模式,會(huì)自動(dòng)提交每一條sql語(yǔ)句,不能算是transaction吧。
          安裝時(shí)要指定mysql支持innodb,./configure --with-innodb。

          2.配置
          安裝后,可以對(duì)innodb做一些配置,在my.cnf或my.ini中的[mysqld]段。
          #存儲(chǔ)目錄,如果不指定默認(rèn)為安裝的data目錄,為空時(shí)以innodb_data_file_path指定路徑為準(zhǔn)
          innodb_data_home_dir =
          #數(shù)據(jù)文件名及大小,默認(rèn)為ibdata1,10m大小。autoextend可以自增,max:2000M文件最大2g,因?yàn)橛械挠脖P有2g文件大小限制。
          innodb_data_file_path = ibdata1:2000M;ibdata2:2000M:autoextend:max:2000M
          # 設(shè)置緩沖池大小
          set-variable = innodb_buffer_pool_size=70M
          set-variable = innodb_additional_mem_pool_size=10M
          #設(shè)置日志文件路徑,默認(rèn)在date目錄下,名稱為ib_logfile...
          innodb_log_group_home_dir =
          #設(shè)置日志文件數(shù)目,默認(rèn)為3
          set-variable = innodb_log_files_in_group=3
          # 設(shè)置日志文件大小
          set-variable = innodb_log_file_size=10M
          # 設(shè)置日志緩沖大小
          set-variable = innodb_log_buffer_size=8M
          # 任何事務(wù)提交前寫入日志,方便故障診斷,請(qǐng)?jiān)O(shè)為1。如果丟失最近的幾個(gè)事務(wù)影響不大的話,設(shè)置為0(默認(rèn)值)。
          innodb_flush_log_at_trx_commit=1
          #設(shè)置超時(shí)時(shí)間
          set-variable = innodb_lock_wait_timeout=50

          注意:innodb不會(huì)自動(dòng)生成目錄,上面所有指定目錄要手工生成。默認(rèn)不用。

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

           

          innodb_data_home_dir

          這是InnoDB表的目錄共用設(shè)置。如果沒有在 my.cnf 進(jìn)行設(shè)置,InnoDB 將使用MySQLdatadir 目錄為缺省目錄。如果設(shè)定一個(gè)空字串,可以在 innodb_data_file_path 中設(shè)定絕對(duì)路徑。

          innodb_data_file_path

          單獨(dú)指定數(shù)據(jù)文件的路徑與大小。數(shù)據(jù)文件的完整路徑由 innodb_data_home_dir 與這里所設(shè)定值的組合。 文件大小以 MB 單位指定。因此在文件大小指定后必有“M” InnoDB 也支持縮寫“G” 1G = 1024M。從 3.23.44 開始,在那些支持大文件的操作系統(tǒng)上可以設(shè)置數(shù)據(jù)文件大小大于 4 GB。而在另一些操作系統(tǒng)上數(shù)據(jù)文件必須小于 2 GB。數(shù)據(jù)文件大小總和至少要達(dá)到 10 MB。在 MySQL-3.23 中這個(gè)參數(shù)必須在 my.cnf 中明確指定。在 MySQL-4.0.2 以及更新版本中則不需如此,系統(tǒng)會(huì)默認(rèn)在 MySQL datadir 目錄下創(chuàng)建一個(gè) 16 MB 自擴(kuò)充(auto-extending)的數(shù)據(jù)文件 ibdata1你同樣可以使用一個(gè) 原生磁盤分區(qū)(RAW raw disk partitions(raw devices)) 作為數(shù)據(jù)文件, 如何在 my.cnf 中詳細(xì)指定它們請(qǐng)查看第 12.1 節(jié)。

          innodb_mirrored_log_groups

          為了保護(hù)數(shù)據(jù)而設(shè)置的日志文件組的拷貝數(shù)目,默認(rèn)設(shè)置為 1。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_log_group_home_dir

          InnoDB 日志文件的路徑。必須與 innodb_log_arch_dir 設(shè)置相同值。 如果沒有明確指定將默認(rèn)在 MySQL datadir 目錄下建立兩個(gè) 5 MB 大小的 ib_logfile... 文件。

          innodb_log_files_in_group

          日志組中的日志文件數(shù)目。InnoDB 以環(huán)型方式(circular fashion)寫入文件。數(shù)值 3 被推薦使用。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_log_file_size

          日志組中的每個(gè)日志文件的大小(單位 MB)。如果 n 是日志組中日志文件的數(shù)目,那么理想的數(shù)值為 1M 至下面設(shè)置的緩沖池(buffer pool)大小的 1/n。較大的值,可以減少刷新緩沖池的次數(shù),從而減少磁盤 I/O。但是大的日志文件意味著在崩潰時(shí)需要更長(zhǎng)的時(shí)間來(lái)恢復(fù)數(shù)據(jù)。 日志文件總和必須小于 2 GB3.23.55 4.0.9 以上為小于 4 GB。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_log_buffer_size

          InnoDB 將日志寫入日志磁盤文件前的緩沖大小。理想值為 1M 8M。大的日志緩沖允許事務(wù)運(yùn)行時(shí)不需要將日志保存入磁盤而只到事務(wù)被提交(commit)。 因此,如果有大的事務(wù)處理,設(shè)置大的日志緩沖可以減少磁盤I/O。 在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_flush_log_at_trx_commit

          通常設(shè)置為 1,意味著在事務(wù)提交前日志已被寫入磁盤, 事務(wù)可以運(yùn)行更長(zhǎng)以及服務(wù)崩潰后的修復(fù)能力。如果你愿意減弱這個(gè)安全,或你運(yùn)行的是比較小的事務(wù)處理,可以將它設(shè)置為 0 ,以減少寫日志文件的磁盤 I/O。這個(gè)選項(xiàng)默認(rèn)設(shè)置為 0

          innodb_log_arch_dir

          The directory where fully written log files would be archived if we used log archiving. 這里設(shè)置的參數(shù)必須與 innodb_log_group_home_dir 相同。 從 4.0.6 開始,可以忽略這個(gè)參數(shù)。

          innodb_log_archive

          這個(gè)值通常設(shè)為 0。 既然從備份中恢復(fù)(recovery)適合于 MySQL 使用它自己的 log files,因而通常不再需要 archive InnoDB log files。這個(gè)選項(xiàng)默認(rèn)設(shè)置為 0

          innodb_buffer_pool_size

          InnoDB 用來(lái)高速緩沖數(shù)據(jù)和索引內(nèi)存緩沖大小。 更大的設(shè)置可以使訪問數(shù)據(jù)時(shí)減少磁盤 I/O。在一個(gè)專用的數(shù)據(jù)庫(kù)服務(wù)器上可以將它設(shè)置為物理內(nèi)存的 80 %。 不要將它設(shè)置太大,因?yàn)槲锢韮?nèi)存的使用競(jìng)爭(zhēng)可能會(huì)影響操作系統(tǒng)的頁(yè)面調(diào)用。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_additional_mem_pool_size

          InnoDB 用來(lái)存儲(chǔ)數(shù)據(jù)字典(data dictionary)信息和其它內(nèi)部數(shù)據(jù)結(jié)構(gòu)(internal data structures)的存儲(chǔ)器組合(memory pool)大小。理想的值為 2M,如果有更多的表你就需要在這里重新分配。如果 InnoDB 用盡這個(gè)池中的所有內(nèi)存,它將從操作系統(tǒng)中分配內(nèi)存,并將錯(cuò)誤信息寫入 MySQL 的錯(cuò)誤日志中。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_file_io_threads

          InnoDB 中的文件 I/O 線程。 通常設(shè)置為 4,但是在 Windows 下可以設(shè)定一個(gè)更大的值以提高磁盤 I/O。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_lock_wait_timeout

          在回滾(rooled back)之前,InnoDB 事務(wù)將等待超時(shí)的時(shí)間(單位 秒)InnoDB 會(huì)自動(dòng)檢查自身在鎖定表與事務(wù)回滾時(shí)的事務(wù)死鎖。如果使用 LOCK TABLES 命令,或在同一個(gè)事務(wù)中使用其它事務(wù)安全型表處理器(transaction safe table handlers than InnoDB),那么可能會(huì)發(fā)生一個(gè) InnoDB 無(wú)法注意到的死鎖。在這種情況下超時(shí)將用來(lái)解決這個(gè)問題。這個(gè)參數(shù)的默認(rèn)值為 50 秒。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_flush_method

          這個(gè)參數(shù)僅僅與 Unix 相關(guān)。這個(gè)參數(shù)默認(rèn)值為 fdatasync。 另一個(gè)設(shè)置項(xiàng)為 O_DSYNC。這僅僅影響日志文件的轉(zhuǎn)儲(chǔ),在 Unix 下以 fsync 轉(zhuǎn)儲(chǔ)數(shù)據(jù)。InnoDB 版本從 3.23.40b 開始,在 Unix 下指定 fdatasync 為使用 fsync 方式、指定 O_DSYNC 為使用 O_SYNC 方式。由于這在某些 Unix 環(huán)境下還有些問題所以在 'data' versions 并沒有被使用。

          innodb_force_recovery

          警告:此參數(shù)只能在你希望從一個(gè)被損壞的數(shù)據(jù)庫(kù)中轉(zhuǎn)儲(chǔ)(dump)數(shù)據(jù)的緊急情況下使用! 可能設(shè)置的值范圍為 1 - 6。查看下面的章節(jié) 'Forcing recovery' 以了解這個(gè)參數(shù)的具體含義。參數(shù)設(shè)置大于 0 的值代表著 InnoDB 防止用戶修改數(shù)據(jù)的安全度。從 3.23.44 開始,這個(gè)參數(shù)可用。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb_fast_shutdown

          InnoDB 缺少在關(guān)閉之前清空插入緩沖。這個(gè)操作可能需要幾分鐘,在極端的情況下可以需要幾個(gè)小時(shí)。如果這個(gè)參數(shù)據(jù)設(shè)置為 1 InnoDB 將跳過(guò)這個(gè)過(guò)程而直接關(guān)閉。從 3.23.44 4.0.1 開始,此參數(shù)可用。從 3.23.50 開始,此參數(shù)的默認(rèn)值為 1

          innodb_thread_concurrency

          InnoDB 會(huì)試圖將 InnoDB 服務(wù)的使用的操作系統(tǒng)進(jìn)程小于或等于這里所設(shè)定的數(shù)值。此參數(shù)默認(rèn)值為 8。如果計(jì)算機(jī)系統(tǒng)性能較低或 innodb_monitor 顯示有很多線程等侍信號(hào),應(yīng)該將這個(gè)值設(shè)小一點(diǎn)。如果你的計(jì)算機(jī)系統(tǒng)有很我的處理器與磁盤系統(tǒng),則可以將這個(gè)值設(shè)高一點(diǎn)以充分利用你的系統(tǒng)資源。建議設(shè)值為處理器數(shù)目+ 磁盤數(shù)目。 從 3.23.44 4.0.1 開始,此參數(shù)可用。在 my.cnf 中以數(shù)字格式設(shè)置。

          innodb還需要使用二進(jìn)制日志文件:

          log-bin指定二進(jìn)制文件名稱,不指定默認(rèn)生成。
          log-bin-index 可以指定索引文件。
          使用 binlog-do-db可以指定記錄的數(shù)據(jù)庫(kù)。
          使用 binlog-ignore-db可以指定不記錄的數(shù)據(jù)庫(kù)。
          注意的是: binlog-do-db 和binlog-ignore-db 一次只指定一個(gè)數(shù)據(jù)庫(kù),指定多個(gè)數(shù)據(jù)庫(kù)需要多個(gè)語(yǔ)句。而且,MySQL會(huì)將所有的數(shù)據(jù)庫(kù)名稱改成小寫, 在指定數(shù)據(jù)庫(kù)時(shí)必須全部使用小寫名字,否則不會(huì)起作用。

          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語(yǔ)句的transaction實(shí)現(xiàn)
          兩種方式:
          如果SET AUTOCOMMIT=0;也就是關(guān)閉了自動(dòng)提交,那么任何commit或rallback語(yǔ)句都可以觸發(fā)事務(wù)提交。
          比如:
           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)
          這樣事務(wù)就算提交了。
          如果SET AUTOCOMMIT=1;也就是開啟了自動(dòng)提交(默認(rèn)值),那么必須要以begin或者START TRANSACTION聲明事務(wù)的開始,然后再以commit或rallback語(yǔ)句都可以觸發(fā)事務(wù)提交。
          比如:
           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)

          像其他關(guān)系型數(shù)據(jù)庫(kù)一樣,也可以使用存儲(chǔ)過(guò)程(procedure)來(lái)封裝事務(wù)。

          5.java程序開發(fā)中的實(shí)現(xiàn)。
          涉及到程序開發(fā)實(shí)現(xiàn)方法就多了。
          一.自己寫方法把mysql的底層transaction命令封裝。我感覺程序開發(fā)中應(yīng)該盡量避免和底層數(shù)據(jù)庫(kù)的過(guò)多交互,我沒有實(shí)現(xiàn)它。
          有人實(shí)現(xiàn)了,下面是他實(shí)現(xiàn)的一個(gè)例子網(wǎng)址:http://dlog.cn/html/diary/showlog.vm?sid=7&log_id=2516
          二.java的jdbc開發(fā)包包含了操作transaction的方法,在java.sql.connection接口里。
          使用他的好處是可以和多種類型數(shù)據(jù)庫(kù)交互。
          三.hibernate等ORM框架工具。
          hibernate 中也封狀了對(duì)transaction的操作,在org.hibernate.Session類中,使用beginTransaction()方法開啟 transaction;使用getTransaction().commit()提交transaction;使用getTransaction(). rollback()方法回滾transaciton。
          四.這是我常用的一種方法,把hibernate的session的方法封裝或者實(shí)現(xiàn)jdbc的connection的接口。



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

          posted on 2007-04-06 13:04 蘆葦 閱讀(7485) 評(píng)論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫(kù)
          主站蜘蛛池模板: 汶上县| 宜兰县| 田阳县| 临朐县| 奎屯市| 江西省| 清水河县| 甘孜县| 高雄县| 吕梁市| 翁牛特旗| 涡阳县| 连云港市| 安溪县| 南陵县| 正蓝旗| 迭部县| 河北省| 兴文县| 泸定县| 滨州市| 东丽区| 双柏县| 淄博市| 洛扎县| 叙永县| 公主岭市| 新丰县| 巴林右旗| 平果县| 洛浦县| 亳州市| 常德市| 体育| 沂源县| 新化县| 威远县| 台江县| 江口县| 安多县| 施秉县|