當前位置:首頁 » 數據倉庫 » mysql多資料庫事務
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

mysql多資料庫事務

發布時間: 2023-08-16 03:37:08

㈠ mysql的事務四個特性以及事務的四個隔離級別

分別是原子性、一致性、隔離性、持久性。

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到資料庫,如果操作失敗則不能對資料庫有任何影響。

一致性是指事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之後都必須處於一致性狀態。舉例來說,假設用戶A和用戶B兩者的錢加起來一共是1000,那麼不管A和B之間如何轉賬、轉幾次賬,事務結束後兩個用戶的錢相加起來應該還得是1000,這就是事務的一致性。

隔離性是當多個用戶並發訪問資料庫時,比如同時操作同一張表時,資料庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個並發事務之間要相互隔離。關於事務的隔離性資料庫提供了多種隔離級別,稍後會介紹到。

持久性是指一個事務一旦被提交了,那麼對資料庫中的數據的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丟失提交事務的操作。例如我們在使用JDBC操作資料庫時,在提交事務方法後,提示用戶事務操作完成,當我們程序執行完成直到看到提示後,就可以認定事務已經正確提交,即使這時候資料庫出現了問題,也必須要將我們的事務完全執行完成。否則的話就會造成我們雖然看到提示事務處理完畢,但是資料庫因為故障而沒有執行事務的重大錯誤。這是不允許的。

在資料庫操作中,在並發的情況下可能出現如下問題:

正是為了解決以上情況,資料庫提供了幾種隔離級別。

資料庫事務的隔離級別有4個,由低到高依次為Read uncommitted(未授權讀取、讀未提交)、Read committed(授權讀取、讀提交)、Repeatable read(可重復讀取)、Serializable(序列化),這四個級別可以逐個解決臟讀、不可重復讀、幻象讀這幾類問題。

雖然資料庫的隔離級別可以解決大多數問題,但是靈活度較差,為此又提出了悲觀鎖和樂觀鎖的概念。

悲觀鎖,它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度。因此,在整個數據處理過程中,將數據處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制。也只有資料庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在本系統的數據訪問層中實現了加鎖機制,也無法保證外部系統不會修改數據。

商品t_items表中有一個欄位status,status為1代表商品未被下單,status為2代表商品已經被下單(此時該商品無法再次下單),那麼我們對某個商品下單時必須確保該商品status為1。假設商品的id為1。
如果不採用鎖,那麼操作方法如下:

但是上面這種場景在高並發訪問的情況下很可能會出現問題。例如當第一步操作中,查詢出來的商品status為1。但是當我們執行第三步Update操作的時候,有可能出現其他人先一步對商品下單把t_items中的status修改為2了,但是我們並不知道數據已經被修改了,這樣就可能造成同一個商品被下單2次,使得數據不一致。所以說這種方式是不安全的。

在上面的場景中,商品信息從查詢出來到修改,中間有一個處理訂單的過程,使用悲觀鎖的原理就是,當我們在查詢出t_items信息後就把當前的數據鎖定,直到我們修改完畢後再解鎖。那麼在這個過程中,因為t_items被鎖定了,就不會出現有第三者來對其進行修改了。需要注意的是,要使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性,因為MySQL默認使用autocommit模式,也就是說,當你執行一個更新操作後,MySQL會立刻將結果進行提交。我們可以使用命令設置MySQL為非autocommit模式: set autocommit=0;
設置完autocommit後,我們就可以執行我們的正常業務了。具體如下:

上面的begin/commit為事務的開始和結束,因為在前一步我們關閉了mysql的autocommit,所以需要手動控制事務的提交。
上面的第一步我們執行了一次查詢操作: select status from t_items where id=1 for update; 與普通查詢不一樣的是,我們使用了 select…for update 的方式,這樣就通過資料庫實現了悲觀鎖。此時在t_items表中,id為1的那條數據就被我們鎖定了,其它的事務必須等本次事務提交之後才能執行。這樣我們可以保證當前的數據不會被其它事務修改。需要注意的是,在事務中,只有 SELECT ... FOR UPDATE 或 LOCK IN SHARE MODE 操作同一個數據時才會等待其它事務結束後才執行,一般 SELECT ... 則不受此影響。拿上面的實例來說,當我執行 select status from t_items where id=1 for update; 後。我在另外的事務中如果再次執行 select status from t_items where id=1 for update; 則第二個事務會一直等待第一個事務的提交,此時第二個查詢處於阻塞的狀態,但是如果我是在第二個事務中執行 select status from t_items where id=1; 則能正常查詢出數據,不會受第一個事務的影響。

使用 select…for update 會把數據給鎖住,不過我們需要注意一些鎖的級別,MySQL InnoDB默認Row-Level Lock,所以只有「明確」地指定主鍵或者索引,MySQL 才會執行Row lock (只鎖住被選取的數據) ,否則MySQL 將會執行Table Lock (將整個數據表單給鎖住)。舉例如下:
1、 select * from t_items where id=1 for update;
這條語句明確指定主鍵(id=1),並且有此數據(id=1的數據存在),則採用row lock。只鎖定當前這條數據。
2、 select * from t_items where id=3 for update;
這條語句明確指定主鍵,但是卻查無此數據,此時不會產生lock(沒有元數據,又去lock誰呢?)。
3、 select * from t_items where name='手機' for update;
這條語句沒有指定數據的主鍵,那麼此時產生table lock,即在當前事務提交前整張數據表的所有欄位將無法被查詢。
4、 select * from t_items where id>0 for update; 或者 select * from t_items where id>1 for update; (註:>在SQL中表示不等於)
上述兩條語句的主鍵都不明確,也會產生table lock。
5、 select * from t_items where status=1 for update; (假設為status欄位添加了索引)
這條語句明確指定了索引,並且有此數據,則產生row lock。
6、 select * from t_items where status=3 for update; (假設為status欄位添加了索引)
這條語句明確指定索引,但是根據索引查無此數據,也就不會產生lock。

樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認為數據一般情況下不會造成沖突,所以只會在數據進行提交更新的時候,才會正式對數據的沖突與否進行檢測,如果發現沖突了,則返回用戶錯誤的信息,讓用戶決定如何去做。實現樂觀鎖一般來說有以下2種方式:

㈡ mysql資料庫腳本事務如何控制

而你的每一次
mysql
-h${HOSTNAME}
-P${PORT}
-u${USERNAME}...
都是一個新的連接(SESSION)AUTOCOMMIT=0
這個僅是對當前SESSION的變數進行了設置,並沒有改變所有的MYSQL事務設置。

㈢ Mysql資料庫中,事務是指什麼如何使用該功能

什麼是事務? x0dx0ax0dx0a事務是邏輯上的一組操作,組成這組操作的各個單元,要不全都成功要不全都失敗,這個特性就是事務 x0dx0ax0dx0a注意:mysql數據支持事務,但是要求必須是innoDB存儲引擎 x0dx0ax0dx0a解決這個問題: x0dx0ax0dx0amysql的事務解決這個問題,因為mysql的事務特性,要求這組操作,要不全都成功,要不全都失敗,這樣就避免了某個操作成功某個操作失敗。利於數據的安全 x0dx0ax0dx0a如何使用: x0dx0ax0dx0a(1)在執行sql語句之前,我們要開啟事務 start transaction; x0dx0ax0dx0a(2)正常執行我們的sql語句 x0dx0ax0dx0a(3)當sql語句執行完畢,存在兩種情況: x0dx0ax0dx0a1,全都成功,我們要將sql語句對資料庫造成的影響提交到資料庫中,committ x0dx0ax0dx0a2,某些sql語句失敗,我們執行rollback(回滾),將對資料庫操作趕緊撤銷 x0dx0ax0dx0a(注意:mysql數據支持事務,但是要求必須是innoDB存儲引擎) x0dx0amysql> create table bank(name varchar(20),money decimal(5,1))engine=innodb defau x0dx0alt charset=utf8; x0dx0ax0dx0amysql> inset into bank values('shaotuo',1000),('laohu',5000); x0dx0ax0dx0amysql> select*from bank; x0dx0a+---------+--------+ x0dx0a| name | money | x0dx0a+---------+--------+ x0dx0a| shaotuo | 1000.0 | x0dx0a| laohu | 5000.0 | x0dx0a+---------+--------+ x0dx0ax0dx0a------沒有成功「回滾」執行rollback x0dx0amysql> start transaction; //開啟事務 x0dx0aQuery OK, 0 rows affected (0.00 sec) x0dx0ax0dx0amysql> update bank set money=money+500 where name='shaotuo' x0dx0aQuery OK, 1 row affected (0.00 sec) x0dx0aRows matched: 1 Changed: 1 Warnings: 0 x0dx0ax0dx0amysql> update bank set moey=money-500 where name='laohu' x0dx0aERROR 1054 (42S22): Unknown column 'moey' in 'field list' x0dx0amysql> rollback; //只要有一個不成功,執行rollback操作 x0dx0aQuery OK, 0 rows affected (0.01 sec) x0dx0ax0dx0amysql> select*from bank; x0dx0a+---------+--------+ x0dx0a| name | money | x0dx0a+---------+--------+ x0dx0a| shaotuo | 1000.0 | x0dx0a| laohu | 5000.0 | x0dx0a+---------+--------+ x0dx0a------成功之後 進行commit操作 x0dx0amysql> start transaction; //開啟事務 x0dx0aQuery OK, 0 rows affected (0.00 sec) x0dx0ax0dx0amysql> update bank set money=money+500 where name='shaotuo' x0dx0aQuery OK, 1 row affected (0.01 sec) x0dx0aRows matched: 1 Changed: 1 Warnings: 0 x0dx0ax0dx0amysql> update bank set money=money-500 where name='laohu' x0dx0aQuery OK, 1 row affected (0.00 sec) x0dx0aRows matched: 1 Changed: 1 Warnings: 0 x0dx0ax0dx0amysql> commit; //兩個都成功後執行commit(只要不執行commit,sql語句不會對真實的資料庫造成影響) x0dx0aQuery OK, 0 rows affected (0.05 sec) x0dx0ax0dx0amysql> select*from bank; x0dx0a+---------+--------+ x0dx0a| name | money | x0dx0a+---------+--------+ x0dx0a| shaotuo | 1500.0 | x0dx0a| laohu | 4500.0 | x0dx0a+---------+--------+

㈣ Mysql資料庫中,事務是指什麼如何使用該功能

MySQL 事務

什麼是事務?

MySQL 事務主要用於處理操作量大,復雜度高的數據。比如說,在人員管理系統中,你刪除一個人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些資料庫操作語句就構成一個事務!

在 MySQL 中只有使用了 Innodb 資料庫引擎的資料庫或表才支持事務。

  • 事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。

  • 事務用來管理 insert,update,delete 語句

一般來說,事務是必須滿足4個條件(ACID):原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。

  • 原子性:一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

  • 一致性:在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續資料庫可以自發性地完成預定的工作。

  • 隔離性:資料庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串列化(Serializable)。

  • 持久性:事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。

在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句後就會馬上執行 COMMIT 操作。因此要顯式地開啟一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。

from 樹懶學堂 - 一站式數據知識平台

㈤ 安裝MySQL事務資料庫都需要哪些步驟

按常規的方法進行安裝
安裝MySQL完成後,啟動MySQL(和PHP搭配之最佳組合)binWinMySQL(和PHP搭配之最佳組合)admin
再退出
運行
MySQL(和PHP搭配之最佳組合)binmydqld-nt--remove
MySQL(和PHP搭配之最佳組合)binMySQL(和PHP搭配之最佳組合)d-max-nt--install
以上二行是去掉不支持事務處理的MySQL(和PHP搭配之最佳組合)服務,改成支持MySQL(和PHP搭配之最佳組合)事務處理的服務
然後在c:下建一個ibdata目錄及iblogs目錄,當然名字可以不一樣,記住這二個名字及盤符,以後要用到,你也可以不建在C盤,然後,打開c:winnt或c:windows目錄下的my.ini,在最後添加:以下內容為程序代碼:
1.innodb_data_file_path=ibdata1:2000M;ibdata2:2000M
2.innodb_data_home_dir=c:ibdata
3.set-variable=innodb_mirrored_log_groups=1
4.innodb_log_group_home_dir=c:iblogs
5.set-variable=innodb_log_files_in_group=3
6.set-variable=innodb_log_file_size=30M
7.set-variable=innodb_log_buffer_size=8M
8.innodb_flush_log_at_trx_commit=1
9.innodb_log_arch_dir=c:iblogs
10.innodb_log_archive=0
11.set-variable=innodb_buffer_pool_size=80M
12.set-variable=innodb_additional_mem_pool_size=10M
13.set-variable=innodb_file_io_threads=4
14.set-variable=innodb_lock_wait_timeout=50
其中
1.innodb_data_file_path=ibdata1:2000M;ibdata2:2000M 這一行中的2000M可以自己改成200m,看你盤的容量大小,MySQL(和PHP搭配之最佳組合)推薦10G及以上的硬碟空間最好用這樣的設置;
以下這一行
1.innodb_data_home_dir=c:ibdata 也可以改成你自己起的目錄,主要是看你自己在剛才建的目錄在哪裡啦
按照以上的方法,你已經安裝MySQL好了MySQL(和PHP搭配之最佳組合)的事務資料庫,不過你要是按照MySQL(和PHP搭配之最佳組合)手冊上的方法安裝,把上面的一段配製放到my.cnf是去的話,可是會出錯哦
好了,現在讓我們試試看是不是安裝完成了,啟動apache(Unix平台最流行的WEB伺服器平台),或iis,在服務里啟動MySQL(和PHP搭配之最佳組合)的服務,打開phpmyadmin,輸入:SHOWvariableslikehave_%
你要是看到下面的結果,那說明你安裝MySQL成功了
以下內容為程序代碼
1.Variable_nameValue
2.have_bdbYES
3.have_innodbYES
4.have_isamYES
5.have_raidNO
6.have_symlinkYES
7.have_opensslNO
8.have_query_cacheYES
9. 註:MySQL(和PHP搭配之最佳組合)的事務處理方法的使用同其它資料庫語法相似,在這里我就不多說了,另外,MySQL(和PHP搭配之最佳組合)將在4.3中實現外鍵及子查詢,簡單的外鍵已經在4.0中都已經實現了,只是不怎麼方便,相信以後會做得更好些。

㈥ python 怎麼操作mysql中多個資料庫

MySQL 的 Binlog 記錄著 MySQL 資料庫的所有變更信息,了解 Binlog 的結構可以幫助我們解析Binlog,甚至對 Binlog 進行一些修改,或者說是「篡改」,例如實現類似於 Oracle 的 flashback 的功能,恢復誤刪除的記錄,把 update 的記錄再還原回去等。本文將帶您探討一下這些神奇功能的實現,您會發現比您想像地要簡單得多。本文指的 Binlog 是 ROW 模式的 Binlog,這也是 MySQL 8 里的默認模式,STATEMENT 模式因為使用中有很多限制,現在用得越來越少了。
Binlog 由事件(event)組成,請注意是事件(event)不是事務(transaction),一個事務可以包含多個事件。事件描述對資料庫的修改內容。
現在我們已經了解了 Binlog 的結構,我們可以試著修改 Binlog 里的數據。例如前面舉例的 Binlog 刪除了一條記錄,我們可以試著把這條記錄恢復,Binlog 裡面有個刪除行(DELETE_ROWS_EVENT)的事件,就是這個事件刪除了記錄,這個事件和寫行(WRITE_ROWS_EVENT)的事件的數據結構是完全一樣的,只是刪除行事件的類型是 32,寫行事件的類型是 30,我們把對應的 Binlog 位置的 32 改成 30 即可把已經刪除的記錄再插入回去。從前面的 「show binlog events」 裡面可看到這個 DELETE_ROWS_EVENT 是從位置 378 開始的,這里的位置就是 Binlog 文件的實際位置(以位元組為單位)。從事件(event)的結構裡面可以看到 type_code 是在 event 的第 5 個位元組,我們寫個 Python 小程序把把第383(378+5=383)位元組改成 30 即可。當然您也可以用二進制編輯工具來改。
找出 Binlog 中的大事務
由於 ROW 模式的 Binlog 是每一個變更都記錄一條日誌,因此一個簡單的 SQL,在 Binlog 里可能會產生一個巨無霸的事務,例如一個不帶 where 的 update 或 delete 語句,修改了全表裡面的所有記錄,每條記錄都在 Binlog 裡面記錄一次,結果是一個巨大的事務記錄。這樣的大事務經常是產生麻煩的根源。我的一個客戶有一次向我抱怨,一個 Binlog 前滾,滾了兩天也沒有動靜,我把那個 Binlog 解析了一下,發現裡面有個事務產生了 1.4G 的記錄,修改了 66 萬條記錄!下面是一個簡單的找出 Binlog 中大事務的 Python 小程序,我們知道用 mysqlbinlog 解析的 Binlog,每個事務都是以 BEGIN 開頭,以 COMMIT 結束。我們找出 BENGIN 前面的 「# at」 的位置,檢查 COMMIT 後面的 「# at」 位置,這兩個位置相減即可計算出這個事務的大小,下面是這個 Python 程序的例子。
切割 Binlog 中的大事務
對於大的事務,MySQL 會把它分解成多個事件(注意一個是事務 TRANSACTION,另一個是事件 EVENT),事件的大小由參數 binlog-row-event-max-size 決定,這個參數默認是 8K。因此我們可以把若干個事件切割成一個單獨的略小的事務
ROW 模式下,即使我們只更新了一條記錄的其中某個欄位,也會記錄每個欄位變更前後的值,這個行為是 binlog_row_image 參數控制的,這個參數有 3 個值,默認為 FULL,也就是記錄列的所有修改,即使欄位沒有發生變更也會記錄。這樣我們就可以實現類似 Oracle 的 flashback 的功能,我個人估計 MySQL 未來的版本從可能會基於 Binlog 推出這樣的功能。
了解了 Binlog 的結構,再加上 Python 這把瑞士軍刀,我們還可以實現很多功能,例如我們可以統計哪個表被修改地最多?我們還可以把 Binlog 切割成一段一段的,然後再重組,可以靈活地進行 MySQL 資料庫的修改和遷移等工作。

㈦ mysql怎麼給操作兩個資料庫的sql加事務

mysql一般表使用innodb引擎才能使用事務,請先確定表引擎為innodb