Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 как создать таблицу вне текущей транзакции?  [new]
Ionah
Member

Откуда: Новосибирск
Сообщений: 290
сабж

как создать таблицу внутри транзакции но вне ее контекста?

Физический смысл такой:
начать транзакцию,
сделать "некоторые действия с данными",
сделать снэпшоты таблиц вне транзакции,
откатить только "некоторые действия с данными"
чтобы получить изначальное состояние
23 мар 05, 11:40    [1407993]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Glory
Member

Откуда:
Сообщений: 104760
1.
- Сделать копию данных в промежуточную таблицу
- Проводить "некоторые действия с данными" не в оригинальной таблице а в промежуточной

2.
Использовать table variables
23 мар 05, 11:44    [1408005]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37100
Сделайте табличную переменную. Действия с ней не логгируются и, соответсвенно, не откатываются rollback'oм.
23 мар 05, 11:44    [1408007]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Ionah
Member

Откуда: Новосибирск
Сообщений: 290
"некоторые действия с данными" затрагивают тучу таблиц

все это потом нужно откатить
чтобы получить исходное состояние
23 мар 05, 11:45    [1408014]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ionah
"некоторые действия с данными" затрагивают тучу таблиц

все это потом нужно откатить
чтобы получить исходное состояние

Не пойму - зачем делать что-то в оригинальных таблицах если потом это надо отменить ?
Вы же снэпшот получить хотите тоже для нескольких таблиц
23 мар 05, 11:52    [1408045]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Ionah
Member

Откуда: Новосибирск
Сообщений: 290
Вы же снэпшот получить хотите тоже для нескольких таблиц


для одной из этой тучи таблиц

вы предлагаете все остальное тестовое окружение создавать
для "некоторых действий с данными"?

триггеры, ограничения целостности, ...

проще сделать бэкап
и потом восстановить базу

но этот вариант неприемлем

нужен механизм для доступа к данным текущей транзакции,
но который сам работает вне ее пределов

может можно еще сделать задержку в основной транзакции
и читать данные из другой сессии с with readuncommitted
23 мар 05, 11:57    [1408072]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Glory
Member

Откуда:
Сообщений: 104760
для одной из этой тучи таблиц
В оригинале было "сделать снэпшоты таблиц вне транзакции"

нужен механизм для доступа к данным текущей транзакции,
но который сам работает вне ее пределов

Нет такого механизма.
Используйте табличные переменные
23 мар 05, 12:02    [1408089]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Ionah
Member

Откуда: Новосибирск
Сообщений: 290
Нет такого механизма.


Ув. Glory, Вы наверное имеете ввиду что вы его не знаете?

Или вы знаете ВСЕ о MSSQL?
23 мар 05, 12:12    [1408122]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
ChA
Member

Откуда: Москва
Сообщений: 11124
Интересно, когда прозвучит сакраментальное: В который раз убеждаюсь, ну и г...о этот M$ $QL $erver, у него даже нет автономных транзакций, как в Oracle....
23 мар 05, 12:14    [1408140]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ув. Glory, Вы наверное имеете ввиду что вы его не знаете?
В MSSQL нет автономных транзакций.
23 мар 05, 12:15    [1408145]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Ionah
Member

Откуда: Новосибирск
Сообщений: 290
может можно добавить удаленный сервер
и создать снэпшоты там, так что MSSQL не станет
откатывать изменения на удаленном сервере?
23 мар 05, 12:36    [1408242]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37100
Ionah
может можно добавить удаленный сервер
и создать снэпшоты там, так что MSSQL не станет
откатывать изменения на удаленном сервере?

Будет.
Imho, тут уже несколько раз предлагалось весьма простое решение Вашей проблемы.
23 мар 05, 12:39    [1408262]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Ionah
Member

Откуда: Новосибирск
Сообщений: 290
да,

похоже, табличные переменные - единственный способ

спасибо за помощь
23 мар 05, 12:42    [1408284]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Роман Дынник
Member

Откуда:
Сообщений: 3324
по поводу автономных транзакций:
как тогда поступать в ситуации когда нужен аудит действий пользователя (лог)?
Например, выполняется хп, в ней стартует транзакция, в ней же нужно обеспечить добавление записи в лог действий пользователя, лог ошибок...
Или для mssql такие вещи лучше выносить с сервера в другое звено?

Posted via ActualForum NNTP Server 1.1

23 мар 05, 12:50    [1408325]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37100
Роман Дынник
по поводу автономных транзакций:
как тогда поступать в ситуации когда нужен аудит действий пользователя (лог)?
Например, выполняется хп, в ней стартует транзакция, в ней же нужно обеспечить добавление записи в лог действий пользователя, лог ошибок...
Или для mssql такие вещи лучше выносить с сервера в другое звено?
Posted via ActualForum NNTP Server 1.1

А перечитать топик с самого начала? И немного подумать? Идея-то на поверхности лежит ...
23 мар 05, 12:54    [1408341]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Роман Дынник
Member

Откуда:
Сообщений: 3324

А перечитать топик с самого начала? И немного подумать? Идея-то на поверхности лежит ...

Для приведенной ситуации идея основанная на глобальной временной таблице для сохранения логов не выглядит очень красиво. Распихивать данные из этой глобальной временной таблицы по джобу чтоли?
С помощью табличных же переменных, придется их возвращать и делать еще один дополнительный вызов для распихивания табличной переменной по логам, что тоже красотой подхода не блещит, а мне вообще не подходит.

Posted via ActualForum NNTP Server 1.1

23 мар 05, 13:19    [1408475]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37100
автор
Для приведенной ситуации идея основанная на глобальной временной таблице для сохранения логов не выглядит очень красиво.

Глобальные временные таблицы тоже подвержены действию rollback если с ними производились действия в транзакции.
автор
С помощью табличных же переменных, придется их возвращать и делать еще один дополнительный вызов для распихивания табличной переменной по логам, что тоже красотой подхода не блещит, а мне вообще не подходит.

Почему?
23 мар 05, 13:42    [1408562]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Роман Дынник
Member

Откуда:
Сообщений: 3324

Почему?

Клиенту давать смому писать логи???

Posted via ActualForum NNTP Server 1.1

23 мар 05, 13:53    [1408598]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37100
Роман Дынник

Почему?

Клиенту давать смому писать логи???
Posted via ActualForum NNTP Server 1.1

Мне всё-таки кажется, что все можно сделать на сервере. Тока это может оказаться не совсем просто и не совсем в лоб, особенно если есть хорошая вложенность процедур, сбоит чего-то в самой внутренней, а транзакция откатывается в вызывающей.
23 мар 05, 13:55    [1408610]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Роман Дынник
Member

Откуда:
Сообщений: 3324
Ну как на сервере?
Одним вызовом не получится никак если транзакция стартует в хп.
Вот пример хп, и как мне для нее сделать логинг?
CREATE PROCEDURE xsp_Ins_Person
(
--<ParamDefBlock>
--<SysParamDefBlock>
 @TicketSID           varchar(36)  = null
,@Debug               int          = 0 
--</SysParamDefBlock>
,@SID                 TSID         = null out
,@ID                  int          = null out

,@SysObjSysClSID      TSID         = null
,@SysObjSysFolderSID  TSID         = null
,@SysObjOwnerSID      TSID         = null
,@SysObjDTCreate      datetime     = null
,@SysObjDTLastChange  datetime     = null
,@SysObjUIDLastChange TSID         = null
,@SysObjIsDel         TFlagYesNo   = null
,@ContragINN          TINN         = null
,@ContragNote         varchar(255) = null
,@PersFirstName       TUserName    = null
,@PersLastName        TUserName    = null
,@PersMiddleName      TUserName    = null
--</ParamDefBlock>
)
AS
BEGIN
 SET NOCOUNT ON
 --<DeclareBlock>
 --<DeclareSysVarBlock>
 declare  @RET_CODE   int
  ,@ERROR_CODE   int
  ,@TRAN_CHECK   int
  ,@TRAN_NAME   sysname
 --</DeclareSysVarBlock>
 --<DeclareVarBlock>
 --</DeclareVarBlock>
 --</DeclareBlock>
 --<PrepareTranBlock>
 set @TRAN_CHECK = case when @@TRANCOUNT > 0 or @@OPTIONS & 2 > 0 then 1 else 0 end
 select  @TRAN_NAME  = OBJECT_NAME(@@PROCID)
  ,@RET_CODE = 0
  ,@ERROR_CODE = 0
 if @TRAN_CHECK = 0 BEGIN TRAN else SAVE TRAN @TRAN_NAME
 --</PrepareTranBlock>
 set @SID=NEWID()
 
 --<ParentInsertBlock>
 SET @RET_CODE = exec xsp_Ins_Contragent
      @TicketSID
     ,@Debug
     ,@SID out
     ,@ID out
  
     ,@SysObjSysClSID
     ,@SysObjSysFolderSID
     ,@SysObjOwnerSID
     ,@SysObjDTCreate
     ,@SysObjDTLastChange
     ,@SysObjUIDLastChange
     ,@SysObjIsDel
     ,@ContragINN
     ,@ContragNote
 --</ParentInsertBlock>
 
 set @ERROR_CODE=@@ERROR
 if (@ERROR_CODE<>0)or(@RET_CODE<>0) GOTO UNDO
 
 --<InsertBlock>
 INSERT INTO Person(SID,ID,PersFirstName,PersLastName,PersMiddleName)
    VALUES(@SID,@ID,@PersFirstName,@PersLastName,@PersMiddleName)
 --</InsertBlock>
 
 set @ERROR_CODE=@@ERROR
 if (@ERROR_CODE<>0)or(@RET_CODE<>0) GOTO UNDO
 --<SuccBlock>
 SUCC:
  if (@TRAN_CHECK=0)and(@@TRANCOUNT>0) COMMIT TRAN
  RETURN(0)
 --</SuccBlock>

 --<UndoBlock>
 UNDO:
  if (@@TRANCOUNT>0)
   if @TRAN_CHECK = 0 ROLLBACK TRAN 
    else ROLLBACK TRAN @TRAN_NAME
  RETURN(1)
 --</UndoBlock>
END
go

Posted via ActualForum NNTP Server 1.1

23 мар 05, 14:06    [1408665]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31596
2Роман Дынник, Ionah

Можно при ошибке писать в лог (sql-сервера).
23 мар 05, 14:14    [1408696]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Роман Дынник
Member

Откуда:
Сообщений: 3324
оно конечно можно, но доставать потом из апп лога не очень удобно.

Posted via ActualForum NNTP Server 1.1

23 мар 05, 14:31    [1408800]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31596
Роман Дынник
оно конечно можно, но доставать потом из апп лога не очень удобно.
Зато самый простой способ. RAISERROR('text', 0, 1)WITH LOG
А доставать админ сможет глазами и вербально пересылать разработчику. Ведь это редко будет происходить, это-же не основная ветка бизнес-процесса?
23 мар 05, 14:39    [1408840]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Glory
Member

Откуда:
Сообщений: 104760
Пример ведения логов с помощью стандартных user-defined trace & events

use tempdb
go
if object_id('dbo.testtable') is not null 
	drop table dbo.testtable
go

if object_id('dbo.testproc') is not null 
	drop procedure dbo.testproc
go

create table dbo.testtable(f1 int)
go

create procedure dbo.testproc
	@trace_id int,
	@event_id int
as

if exists(SELECT *FROM ::fn_trace_geteventinfo(@trace_id) WHERE EventID= @event_id)
	EXEC sp_trace_generateevent @event_class = @event_id, @userinfo = N'Inserting row into test table', @userdata = 0x1
insert dbo.testtable(f1) values(1)

if exists(SELECT *FROM ::fn_trace_geteventinfo(@trace_id) WHERE EventID= @event_id)
	EXEC sp_trace_generateevent @event_class = @event_id, @userinfo = N'Inserted row into test table', @userdata = 0x2
go

/*simulate external batch which creates trace*/
declare @rc int, @trace_id int, @trace_file nvarchar(128), @maxtracesize bigint, @on bit, @trace_file2 nvarchar(256), @event_id int, @err int
set @trace_file = N'c:\tr1'
set @trace_file2 = @trace_file + N'.trc'
set @maxtracesize = 10
set @event_id = 82
exec @rc = sp_trace_create @traceid=@trace_id OUTPUT, 
	@options=4,  --SHUTDOWN_ON_ERROR
	@tracefile = @trace_file, --trace file location
	@maxfilesize=@maxtracesize -- trace file max size
if @rc = 0
	begin
	/*turn on user-defined event #82(you can choose 82-91)*/
	set @on = 1
	set @err = 0
	/*
	1 - Text Data 
	2 - Binary Data
	3 - Database ID
	6 - NT Domain Name
	7 - NT User Name
	8 - Host Name
	10 - Application Name
	11 - Login Name
	26 - Server Name
	41 - Login SID
	*/
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 1, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 2, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 3, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 6, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 7, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 8, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 10, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 11, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 26, @on = @on
	set @err = @err + @rc
	exec @rc = sp_trace_setevent @traceid = @trace_id, @eventid = @event_id , @columnid = 41, @on = @on
	set @err = @err + @rc
	if @err = 0
		begin
			/*Start the specified trace.*/
			exec @rc = sp_trace_setstatus @trace_id, 1
			if @rc = 0
				begin
					/*table before transaction*/
					select *  from dbo.testtable
					begin transaction 
					exec dbo.testproc @trace_id, @event_id 
					/*table inside transaction*/
					select *  from dbo.testtable
					rollback transaction
					/*table after transaction*/
					select *  from dbo.testtable
				end
			else
				raiserror('Can''t start trace. Error code %i', 16,1, @rc)
		end
	else
		raiserror('Can''t set event for trace. Error code %i', 16,1, @rc)

	/*Stop the specified trace.*/
	exec @rc = sp_trace_setstatus @trace_id, 0
	if @rc <> 0
		raiserror('Can''t stop trace. Error code %i', 16,1, @rc)
	/*Close the specified trace.*/
	exec @rc = sp_trace_setstatus @trace_id, 2
	if @rc <> 0
		raiserror('Can''t close trace. Error code %i', 16,1, @rc)
	end
else
	raiserror('Can''t create trace. Error code %i', 16,1, @rc)

SELECT TextData, BinaryData, NTUserName, NTDomainName, HostName, ApplicationName, LoginName, SPID,
	ServerName, EventClass, LoginSID
FROM ::fn_trace_gettable(@trace_file2, default)

declare @cmd nvarchar(4000)
set @cmd  = N'del '+@trace_file2
exec master..xp_cmdshell @cmd
10 user-defined trace-ов можно засунуть в процедуру, которая будет срабатывать при старте сервера.
23 мар 05, 15:25    [1409184]     Ответить | Цитировать Сообщить модератору
 Re: как создать таблицу вне текущей транзакции?  [new]
Роман Дынник
Member

Откуда:
Сообщений: 3324
спасибо за хороший пример.

Posted via ActualForum NNTP Server 1.1

23 мар 05, 18:26    [1410117]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить