操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    1.數據庫事務特性

    我們都知道mysql數據庫的事務四大特性ACID

    2.臟讀、幻讀、不可重復讀

    臟讀:?臟讀是事務2讀取到了事務1未提交的數據

    不可重復讀:?事務1對數據讀取后,事務2對其數據進行修改,事務1再次讀取數據時,得到和第一次讀取不同的數據。

    幻讀?事務1對某數據讀取后,事務2對其數據進行刪除或者添加記錄,當事務1再次讀取時發現記錄數減少或者增加了

    3. mysql事務隔離級別

    以下是各個隔離級別所對臟讀、幻讀、不可重復讀的支持情況,默認下mysql的隔離級別是可重復讀。

    4. 未提交讀產生臟讀演示案例

    我們在連接1中,設置當前會話事務隔離級為未提交讀,之后開啟事務向數據庫里面插入了一條記錄,并不手動執行 語句,此時事務處于未提交狀態:

    svn linux 創建版本庫_網站數據庫創建失敗_pos機交易失敗數據接收失敗

    此時在連接2中設置隔離就級別為未提交讀,并查詢數據表,此時結果為:

    此時可以看到連接2是可以查詢到連接1為提交事務的數據,所有此時就會產生臟讀

    4. 已提交讀會不會產生臟讀?

    我們將數據庫的隔離級別修改為已提交讀,并開啟事務,向表中插入一條數據,不執行:

    此時我們再打開連接2,查詢:

    此時我們可以看到連接2是讀取不到連接1未提交的數據的。

    小結:mysql提供了4種隔離級別網站數據庫創建失敗,每個級別對臟讀、不可重復讀、幻讀 這三者提供了不同的解決,這4種隔離級別自上而下(上表中),能解決問題的能力越強。在上表中最安全的級別則是 可串行化,但是mysql為什么默認的隔離級別不是它呢,原因是 因為隔離級別越高,其并發性能越低。

    網站數據庫創建失敗_svn linux 創建版本庫_pos機交易失敗數據接收失敗

    5. JDBC事務控制

    JDBC 是 Java 語言中用來規范客戶端程序如何來訪問數據庫的應用程序接口,提供了查詢和更新數據庫中數據的方法。JDBC 也是 Sun 的商標(現在屬于 ),是面向關系型數據庫的。

    最原始的JDBC數據庫連接方式,如下所示:

    public?void?updateCoffeeSales()throws?SQLException {
    ????try?{
    ????????//獲取連接
    ????????Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
    ????????//關閉自動提交
    ????????con.setAutoCommit(false);
    ????????//DML數據庫操作
    ????????...
    ????????//手動提交事務
    ?????????con.commit();
    ?????????
    ????????} catch?(SQLException e ) {
    ????????????//出現異常回滾
    ????????????con.rollback();
    ???????
    ????????} finally?{
    ????????//關閉連接等操作
    ????}
    }

    在本段代碼塊中,在JDBC處理事務時我們需要手動的進行事務提交,當發生異常時調用連接對象的回滾方法進行回滾操作。在此也可見事務最基本的依賴是數據庫連接對象,

    6.的事務支持6.1 事務管理器

    并不自己實現事務的管理,而是給出來一個抽象的事務管理接口或者超類,需要其他db框架來具體實現。提供的抽象事務管理器接口:

    // Spring提供的事務管理器頂級接口
    public?interface?TransactionManager?{

    }
    --------------
    public?interface?PlatformTransactionManager?extends?TransactionManager?{
    ????????// 根據事務定義獲取事務狀態
    ?????TransactionStatus getTransaction(@Nullable TransactionDefinition definition)throws?TransactionException;
    ?????//提交事務
    ?????void?commit(TransactionStatus status)?throws?TransactionException;
    ?????//回滾事務
    ?????void?rollback(TransactionStatus status)?throws?TransactionException;
    }

    svn linux 創建版本庫_pos機交易失敗數據接收失敗_網站數據庫創建失敗

    由以上兩張圖可以見得 管理器所在的包為-jdbc中,是一個第三方的DB框架。并不自己實現事務的管理,而是給出來一個抽象的事務管理接口或者超類,需要其他db框架來具體實現

    6.2關鍵名詞解釋:

    :這是提供的一個事務管理器的抽象接口,接口里面定義了基礎的事務方法。

    public?interface?PlatformTransactionManager?extends?TransactionManager?{

    ????//返回當前活動的事務或創建一個新的事務
    ?TransactionStatus?getTransaction(@Nullable?TransactionDefinition definition)
    ???throws?TransactionException;

    ?//提交給定事務
    ?void?commit(TransactionStatus status) throws?TransactionException;

    ?//回滾指定事務
    ?void?rollback(TransactionStatus status) throws?TransactionException;

    }

    n:事務的定義,在里面定義了一些事務傳播行為和事務隔離級別如:

    public?interface?TransactionDefinition?{
    //------事務傳播行為------

    //支持當前事務; 如果不存在,則創建一個新的。
    int?PROPAGATION_REQUIRED = 0;
    // 支持當前事務; 如果不存在,則以非事務方式執行。
    int?PROPAGATION_SUPPORTS = 1;
    //支持當前事務;如果沒有當前事務,拋出異常
    int?PROPAGATION_MANDATORY = 2;
    //創建一個新事務,掛起當前事務(如果存在)。
    int?PROPAGATION_REQUIRES_NEW = 3;
    //不支持當前事務;而是始終以非事務方式執行。
    int?PROPAGATION_NOT_SUPPORTED = 4;
    //不支持當前事務;如果當前事務,拋出異常
    int?PROPAGATION_NEVER = 5;
    //如果當前事務存在,則在嵌套事務中執行,
    int?PROPAGATION_NESTED = 6;

    //------事務隔離級別------
    //使用底層數據存儲的默認隔離級別。
    int?ISOLATION_DEFAULT = -1;
    //未提交讀
    int?ISOLATION_READ_UNCOMMITTED = 1;
    //已提交讀
    int?ISOLATION_READ_COMMITTED = 2;
    //可重復讀
    int?ISOLATION_REPEATABLE_READ = 4;
    //串行化
    int?ISOLATION_SERIALIZABLE = 8;

    // 使用底層事務系統的默認超時
    int?TIMEOUT_DEFAULT = -1;

    // 在接口中提供默認的事務傳播行為方法
    default?int?getPropagationBehavior() {
    ??return?PROPAGATION_REQUIRED;
    ?}
    //默認事務隔離級別
    default?int?getIsolationLevel() {
    ??return?ISOLATION_DEFAULT;
    ?}

    }

    :事務保存結點,當一個方法中有多個數據庫修改操作,發生異常時我們并不想回滾全部操作,而只想回滾到某個節點,此時我們需要手動創建回滾的節點,這個接口中提供了三個方法(具體實現是DB框架)如下:

    public?interface?SavepointManager?{
    ????//創建一個新的保存點。可以回滾到特定的保存點
    ?Object createSavepoint()?throws?TransactionException;
    ?//回滾到給定的保存點。
    ?void?rollbackToSavepoint(Object savepoint)?throws?TransactionException;
    ?//顯式釋放給定的保存點。
    ?void?releaseSavepoint(Object savepoint)?throws?TransactionException;
    ?}

    :事務當前狀態的通用表示。

    public?interface?TransactionExecution?{
    ??//返回當前事務是否為新事務;
    ?boolean?isNewTransaction();
    ??//設置事務僅回滾
    ?void?setRollbackOnly();
    ?//返回事務是否已標記為僅回滾
    ?boolean?isRollbackOnly();
    ????//返回該事務是否完成,
    ?boolean?isCompleted();

    }

    pos機交易失敗數據接收失敗_svn linux 創建版本庫_網站數據庫創建失敗

    :事務狀態表示

    public?interface?TransactionStatus?extends?TransactionExecution, SavepointManager, Flushable?
    ????// 事務內部是否有保存結點
    ?boolean?hasSavepoint()
    ;
    ?// 刷新
    ?@Override
    ?void?flush();
    }

    6.2 編程式事務

    中推薦使用接口來實現編程式事務:

    @RequestMapping("test")
    public?class?TestTx?{
    ????@Autowired
    ????private?TransactionTemplate transactionTemplate;
    ????@Autowired
    ????private?IResourceAdminService iResourceAdminService;
    ????@GetMapping()
    ????public?void?test(){
    ????????transactionTemplate.execute(new?TransactionCallbackWithoutResult() {
    ????????????@Override
    ????????????protected?void?doInTransactionWithoutResult(TransactionStatus status)?{
    ????????????????try?{
    ????????????????????ResourceAdmin resourceAdmin = new?ResourceAdmin();
    ????????????????????resourceAdmin.setName("張三");
    ????????????????????resourceAdmin.setPassword("123456");
    ????????????????????// 數據庫保存操作
    ????????????????????boolean?save = iResourceAdminService.save(resourceAdmin);
    ????????????????????if(save){
    ????????????????????????log.info("數據庫保存1成功");
    ????????????????????}
    ????????????????????// 模擬異常
    ????????????????????int?i=5/0;
    ????????????????}catch?(Exception e){
    ????????????????????e.printStackTrace();
    ????????????????????status.setRollbackOnly();
    ????????????????????log.error("發生異常回滾事務");
    ????????????????}
    ????????????}
    ????????});
    ????}
    }

    6.3 淺淡源碼中提供的方法:

    @Override
    ?@Nullable
    ?public? T execute(TransactionCallback action)?throws?TransactionException {
    ??Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");

    ??if?(this.transactionManager instanceof?CallbackPreferringPlatformTransactionManager) {
    ???return?((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
    ??}
    ??else?{
    ??????// 1.根據當前事務管理器獲取事務狀態
    ???TransactionStatus status = this.transactionManager.getTransaction(this);
    ???T result;
    ???try?{
    ???//2.事務操作
    ????result = action.doInTransaction(status);
    ???}
    ???catch?(RuntimeException | Error ex) {
    ????// Transactional code threw application exception -> rollback
    ???//3.異常回滾
    ????rollbackOnException(status, ex);
    ????throw?ex;
    ???}
    ???catch?(Throwable ex) {
    ????// Transactional code threw unexpected exception -> rollback
    ????rollbackOnException(status, ex);
    ????throw?new?UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
    ???}
    ???//4.事務管理器提交事務
    ???this.transactionManager.commit(status);
    ???return?result;
    ??}
    ?}

    方法的參數是一個函數式接口:

    ( )方法是我們需要重寫的

    @FunctionalInterface
    public?interface?TransactionCallback<T> {
    ????//當使用excute方法時需要是重寫這個方法
    ?@Nullable
    ?T doInTransaction(TransactionStatus status);

    }

    網站數據庫創建失敗_pos機交易失敗數據接收失敗_svn linux 創建版本庫

    (,ex)方法實現:

    private?void?rollbackOnException(TransactionStatus status, Throwable ex)?throws?TransactionException {
    ??Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");

    ??logger.debug("Initiating transaction rollback on application exception", ex);
    ??try?{
    ??????// 使用事務管理器會滾事務
    ???this.transactionManager.rollback(status);
    ??}
    ??catch?(TransactionSystemException ex2) {
    ???logger.error("Application exception overridden by rollback exception", ex);
    ???ex2.initApplicationException(ex);
    ???throw?ex2;
    ??}
    ??catch?(RuntimeException | Error ex2) {
    ???logger.error("Application exception overridden by rollback exception", ex);
    ???throw?ex2;
    ??}
    ?}

    (,ex)方法原理也是調用了管理器的方法,進行事務回滾

    根據事務結點創建回滾事務

    在上文中我們提到這個接口,這個接口中三個方法網站數據庫創建失敗,其中有一個創建事務節點和回滾到指定事務結點的方法,下面例子將演示這個兩個方法的用法:

    Object savepoint=null;
    ????????????try?{
    ????????????????ResourceAdmin resourceAdmin = new?ResourceAdmin();
    ????????????????resourceAdmin.setName("張三");
    ????????????????resourceAdmin.setPassword("123456");
    ????????????????// 數據庫保存操作
    ????????????????boolean save = iResourceAdminService.save(resourceAdmin);
    ????????????????if(save){
    ????????????????????log.info("數據庫保存1成功");
    ????????????????}
    ????????????????// 創建事務結點
    ????????????????savepoint = status.createSavepoint();
    ????????????????resourceAdmin.setName("李四");
    ????????????????// 數據庫保存操作
    ????????????????save = iResourceAdminService.save(resourceAdmin);
    ????????????????if(save){
    ????????????????log.info("數據庫保存2成功");
    ????????????????}
    ????????????????// 模擬異常
    ????????????????int?i=5/0;
    ????????????}catch?(Exception e){
    ????????????????e.printStackTrace();
    ????????????????log.error("發生異常回滾事務");
    ????????????????// 回滾到指定事務節點
    ????????????????status.rollbackToSavepoint(savepoint);
    ????????????}

    在以上代碼塊中,我們保存張三用戶成功后,創建了一個事務節點,之后又保存了李四用戶,在異常處理模塊中回滾到保存李四之前,如果代碼運行成功那么數據庫中只會有存在張三用戶,運行測試:

    通過上圖我們可以發現事務確實是回滾到了保存李四用戶之前的。

    補充:其實在以上例子中我們重寫方法時,如果在方法內捕獲異常時我們不自己調用.()方法回滾事務,模板方法也是會幫我們進行事務回滾和提交的。如下圖:

    我們的事務操作代碼其實是放在.();中運行的,只是把自己的數據庫操作語句嵌入到該方法中,所以如果我們調用方法時忘記進行回滾操作,這個模板方法也是會自動幫我們進行事務的提交和回滾,所以不會造成阻塞等問題。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有