Chuyển đến nội dung chính

Transaction trong SQL

Transaction là gì?

Transaction (giao dịch) được dùng để đảm bảo tính toàn vẹn dữ liệu khi xảy ra cập nhật.
Khi một transaction bao gồm nhiều lệnh cập nhật, nó đảm bảo tất cả các cập nhật đều được thực hiện thành công, hoặc trong trường hợp một lệnh gặp sự cố toàn bộ transaction bị hủy bỏ. Khi đó dữ liệu trở về trạng thái như trước khi xảy ra transaction. Nói cách khác transaction ngăn chặn tình huống dữ liệu được cập nhật nửa chừng, trong đó một phần được cập nhật còn một phần bị bỏ qua.
Cú pháp:

BEGIN TRAN
   -- command 1
   -- command 2
   -- ...
COMMIT

Transaction Control

Các lệnh sau đây dùng để điều khiển transaction:

  • COMMIT − những cập nhật dữ liệu sẽ được xác nhận vào trong database, transaction được đóng lại và các khóa (lock) trên các bảng được cập nhật được thả ra.
  • ROLLBACK – trả lại dữ liệu trước khi thay đổi.
  • SAVEPOINT – Tạo ra savepoint được dùng để Rollback.
  • SET TRANSACTION – Đặt tên cho 1 transaction.
Giả sử bạn có 1 bảng Customer với các field: ID, Name, Age, Address, Salary
CREATE TABLE [dbo].[Customers](
 [Id] [uniqueidentifier] NOT NULL,
 [Name] [nvarchar](500) NOT NULL,
 [Age] [int] NOT NULL,
 [Address] [nvarchar](max) NULL,
 [Salary] [decimal](18, 0) NULL,
 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


ALTER TABLE [dbo].[Customers] ADD  CONSTRAINT [DF_Customers_Id]  DEFAULT (newid()) FOR [Id]

Thêm đoạn dữ liệu giả như sau:
INSERT INTO [dbo].[Customers] ([Id], [Name], [Age], [Address], [Salary])
     VALUES( newid(), 'Mohamed Salah', 18, 'Dubai', 2000)

INSERT INTO [dbo].[Customers] ([Id], [Name], [Age], [Address], [Salary])
     VALUES( newid(), 'Angela Merkel', 52, 'Germany', 2000)

INSERT INTO [dbo].[Customers] ([Id], [Name], [Age], [Address], [Salary])
     VALUES( newid(), 'Victoria', 20, 'England', 2000)

INSERT INTO [dbo].[Customers] ([Id], [Name], [Age], [Address], [Salary])
     VALUES( newid(), 'David', 18, 'America', 2000)

INSERT INTO [dbo].[Customers] ([Id], [Name], [Age], [Address], [Salary])
     VALUES( newid(), 'Tim', 18, 'United Stated', 2000)

Lệnh ROLLBACK

Lệnh ROLLBACK là lệnh giao dịch được sử dụng để hoàn tác các giao dịch chưa được lưu vào cơ sở dữ liệu. Lệnh này chỉ có thể được sử dụng để hoàn tác các giao dịch kể từ khi lệnh COMMIT hoặc ROLLBACK cuối cùng được phát hành.

BEGIN TRANSACTION;

DELETE FROM CUSTOMERS WHERE AGE = 18;

IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;

Dữ liệu Customer ko bị xóa nếu dùng lệnh Rollback transaction

Hàm Try … catch

SQLServer Transact-SQL cung cấp cơ chế kiểm soát lỗi bằng TRY … CATCH như trong các ngôn ngữ lập trình phổ dụng hiện nay (Java, C, PHP).
Cú pháp:

-- Syntax for SQL Server, Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse  
BEGIN TRY  
     { sql_statement | statement_block }  
END TRY  
BEGIN CATCH  
     [ { sql_statement | statement_block } ]  
END CATCH  
[ ; ]  
Để nhận thông tin lỗi, ta có các hàm:

  • ERROR_NUMBER() returns the number of the error.
  • ERROR_SEVERITY() returns the severity.
  • ERROR_STATE() returns the error state number.
  • ERROR_PROCEDURE() returns the name of the stored procedure or trigger where the error occurred.
  • ERROR_LINE() returns the line number inside the routine that caused the error.
  • ERROR_MESSAGE() returns the complete text of the error message. The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.

Lưu ý: các hàm trên chỉ được gọi trong phạm vi catch block.
Ví dụ:
Bạn tạo 1 stored procedure để lấy thông tin error:

-- Create procedure to retrieve error information.  
CREATE PROCEDURE usp_GetErrorInfo  
AS  
SELECT  
    ERROR_NUMBER() AS ErrorNumber  
    ,ERROR_SEVERITY() AS ErrorSeverity  
    ,ERROR_STATE() AS ErrorState  
    ,ERROR_PROCEDURE() AS ErrorProcedure  
    ,ERROR_LINE() AS ErrorLine  
    ,ERROR_MESSAGE() AS ErrorMessage;  
GO  
Và bạn thực hiện hàm:

BEGIN TRY  
    -- Generate divide-by-zero error.  
    SELECT 1/0;  
END TRY  
BEGIN CATCH  
    -- Execute error retrieval routine.  
    EXECUTE usp_GetErrorInfo;  
END CATCH;
Bạn có kết quả:

Sử dụng Try..catch với transaction 

Trường hợp xuất hiện lỗi, bạn sử dụng lệnh Rollback để revert lại data. Nếu không xuất hiện lỗi, bạn dùng lệnh commit để lưu data.

BEGIN TRANSACTION;  

BEGIN TRY  
    -- Generate a divide-by-zero error.  
    select 1/0
END TRY  
BEGIN CATCH  
    SELECT   
        ERROR_NUMBER() AS ErrorNumber  
        ,ERROR_SEVERITY() AS ErrorSeverity  
        ,ERROR_STATE() AS ErrorState  
        ,ERROR_PROCEDURE() AS ErrorProcedure  
        ,ERROR_LINE() AS ErrorLine  
        ,ERROR_MESSAGE() AS ErrorMessage;  

    IF @@TRANCOUNT > 0  
        ROLLBACK TRANSACTION;  
END CATCH;  

IF @@TRANCOUNT > 0  
    COMMIT TRANSACTION;  
GO  
Nếu bạn thực hiện nhiều lệnh trong try… catch, bạn phải sử dụng option: XACT_ABORT
Mặc định giá trị này = OFF
XACT_ABORT = OFF: SQL Server sẽ chỉ hủy bỏ lệnh gây ra lỗi trong transaction và vẫn cho các lệnh khác thực hiện tiếp, nếu lỗi xảy ra được đánh giá là không nghiêm trọng.
XACT_ABORT = ON: khi gặp bất kỳ lỗi nào nó hủy bỏ toàn bộ transaction và quay lui trở lại như lúc ban đầu.
Ta có template:

SET XACT_ABORT ON
BEGIN TRAN
BEGIN TRY
   -- command 1
   -- command 2
  -- ...
COMMIT
END TRY
BEGIN CATCH
   ROLLBACK
   DECLARE @ErrorMessage VARCHAR(2000)
   SELECT @ErrorMessage = 'Error: ' + ERROR_MESSAGE()
   RAISERROR(@ErrorMessage, 16, 1)
END CATCH
RAISERROR để báo cho ứng dụng biết thủ tục đã gây ra lỗi và truyền thông báo lỗi cho ứng dụng. VD:
-- SET XACT_ABORT ON will cause the transaction to be uncommittable  
-- when the constraint violation occurs.   
SET XACT_ABORT ON;  

BEGIN TRY  
    BEGIN TRANSACTION;   
        Select 1/0 

    -- If the DELETE statement succeeds, commit the transaction.  
    COMMIT TRANSACTION;  
END TRY  
BEGIN CATCH  
    -- Execute error retrieval routine.  
    EXECUTE usp_GetErrorInfo;  

    -- Test XACT_STATE:  
        -- If 1, the transaction is committable.  
        -- If -1, the transaction is uncommittable and should   
        --     be rolled back.  
        -- XACT_STATE = 0 means that there is no transaction and  
        --     a commit or rollback operation would generate an error.  

    -- Test whether the transaction is uncommittable.  
    IF (XACT_STATE()) = -1  
    BEGIN  
        PRINT  
            N'The transaction is in an uncommittable state.' +  
            'Rolling back transaction.'  
        ROLLBACK TRANSACTION;  
    END;  

    -- Test whether the transaction is committable.  
    IF (XACT_STATE()) = 1  
    BEGIN  
        PRINT  
            N'The transaction is committable.' +  
            'Committing transaction.'  
        COMMIT TRANSACTION;     
    END;  
END CATCH;  

Tham khảo

http://www.sqlviet.com/blog/su-dung-transaction-trong-sql-server
https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql

Chúc các bạn thành công!
Nhatkyhoctap's blog

Nhận xét

  1. Unit of work
    https://dotnettutorials.net/lesson/unit-of-work-csharp-mvc/

    Trả lờiXóa
  2. According to, http://msdn.microsoft.com/en-us/library/ms971497, you must close the datareader before you process the output parameters.

    Trả lờiXóa

Đăng nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.