반응형

매번 컴퓨터 사용을 끝내고 윈도우를 종료했다가 다시 부팅하면 또다시 기본적인 프로그램을 실행시켜야 하고 그 전날 또는 마지막 작업한 환경을 불러오는 등의 번거로운 과정을 반복해야 합니다.

잠깐 동안 컴퓨터를 사용하지 않는 경우라면 절전모드를 이용할 수도 있지만, 장시간 또는 사무실과 같이 퇴근하고 다음날 다시 켜야 하는 경우에는 '최대 절전 모드'를 활용하면 불필요한 전력을 낭비하지도 않고 컴퓨터를 끄기 직전의 상태를 그대로 원복 시켜 주기 때문에 곧바로 마지막 작업한 이후의 업무를 신속하게 이어갈 수 있습니다.

방법은 간단합니다. 윈도우 시작 > 전원 버튼을 누르면 나오는 메뉴에서 최대 절전 모드를 선택하면 메모리를 dump 해서 하드디스크에 저장한 후 컴퓨터가 종료하게 됩니다.

그런데 만약 다음과 같이 최대 절전 모드 메뉴가 보이지 않는다면 이를 아래의 과정을 통해서 활성화시켜야 합니다.

우선 명령 프롬프트를 열고 다음과 같이 입력하여 최대 절전 모드 기능을 사용할 수 있도록 합니다.

powercfg /h on

다음으로 시작 메뉴 검색창에서 '전원'을 입력하여 '전원 및 절전 설정'을 선택하고 다시 '추가 전원 설정'을 선택합니다.

제어판의 전원 옵션 창이 뜨면 '전원 단추 작동 설정'을 선택합니다.

이어지는 화면에서 '현재 사용할 수 없는 설정 변경'을 선택합니다.

종료 설정 옵션 하위의 '최대 절전 모드'를 선택(체크)하고 저장 버튼을 누릅니다.
참고로 '전원 단추를 누를 때:'의 옵션으로 최대 절전 모드를 지정해 놓으면 컴퓨터 전원 버튼만으로 최대 절전 모드 사용이 가능합니다.

이제 윈도우 시작 > 전원 버튼을 누르면 '최대 절전 모드' 항목이 나타나게 됩니다. 

반응형

이따금 SQL서버에서
"메시지 3998, 커밋할 수 없는 트랜잭션이 일괄 처리 맨 끝에서 검색되었습니다. 트랜잭션이 롤백됩니다."
라는 오류가 발생하는 경우가 있습니다.

기술적 내용을 알고나면 지극히 당연한 오류 메시지인데, 그 전에는 도대체 무슨 뜻인지 이해하기가 쉽지 않습니다.

SQL서버에서 명시적으로 트랜잭션을 시작하는 경우, 런타임 중에 오류가 발생하면 해당 트랜잭션에 대하여 직접 완료(커밋 또는 롤백)처리를 해야 하는 모드와 SQL서버가 자동으로 롤백 처리해 주는 모드가 있습니다.

다음 명령을 통해서 모드 변경이 가능 합니다.

SET XACT_ABORT { ON | OFF }

T-SQL 디폴트는 OFF 상태 이며, 이 때는 직접 완료처리를 해야 합니다.

USE AdventureWorks2014
GO

SET XACT_ABORT OFF;
GO

BEGIN TRANSACTION; --- ①

SELECT 10 /0       --- ②
SELECT TOP 1 * FROM Sales.Store    --- ③

SELECT @@TRANCOUNT as trnCount

① 에서 명시적 트랜잭션이 시작 되었습니다.
② 에서 0으로 나누기 오류가 발생 됩니다. 그러나 다음 행의 쿼리가 계속 수행 됩니다.
③ SELECT 문이 정상적으로 수행 됩니다.

결과는 다음과 같습니다.

이 시점에서 @@TRANCOUNT는 보시는 바와 같이 1 입니다.
따라서 개발자가 롤백을 하든지 커밋을 하든지 직접 해야 합니다.
물론 위에서는 UPDATE, DELETE 가 없으므로 커밋을 하든 롤백을 하든 결과가 달라질 것은 없습니다.
XACT_ABORT가 OFF 상태일 때는 런타임 오류가 발생하여도 오류가 발생된 이후의 쿼리가 계속 수행되고
트랜잭션 상태가 유지 됩니다.

이제 XACT_ABORT가 ON인 경우를 보겠습니다.

USE AdventureWorks2014
GO

SET XACT_ABORT ON;   --- ①
GO

BEGIN TRANSACTION;

SELECT 10 /0   --- ②
SELECT TOP 1 * FROM Sales.Store

SELECT @@TRANCOUNT as trnCount

① 에서 XACT_ABORT가 ON으로 변경 되었고, 나머지 쿼리는 전과 동일 합니다.

결과는 다음과 같습니다.

② 에서 0 나누기 오류가 발생하자 그 이후의 쿼리는 수행되지 않고 트랜잭션이 종료되고 자동으로 롤백이 됩니다.
따라서 이때 개발자가 직접 롤백처리 하고자 하면 오류가 발생 합니다.

그럼 "커밋할 수 없는 트랜잭션이 일괄 처리 맨 끝에서 검색되었습니다. 트랜잭션이 롤백됩니다." 오류는 언제 발생하는 걸까요?

다음 쿼리의 실행 결과를 보겠습니다.

USE AdventureWorks2014
GO

SET XACT_ABORT ON;
GO

BEGIN TRANSACTION;
BEGIN TRY   --- ①
    SELECT * FROM person.Person WHERE BusinessEntityID = 1

    INSERT INTO person.personPhone (BusinessEntityID, PhoneNumber, PhoneNumberTypeID)
    VALUES (1, '697-555-0142', 1)    --- ②

    COMMIT
END TRY
BEGIN CATCH  --- ③
    SELECT XACT_STATE() AS XACTSTATE,  ERROR_NUMBER() AS ERR_NUMBER,   --- ④
           ERROR_MESSAGE() AS ERR_MESSAGE 
END CATCH
GO

SELECT @@TRANCOUNT as trnCount

명시적 트랜잭션 실행 후,
① 에서 TRY/CATCH를 처리하고 있습니다.
② 에서 PRIMARY KEY 제약 조건 위반(중복 키 삽입) 오류가 발생 됩니다.
③ TRY 내에서 발생된 오류(예외)로 인해서 CATCH로 제어가 넘어 오게 됩니다.

드디어 "커밋할 수 없는 트랜잭션이 일괄 처리 맨 끝에서 검색되었습니다. 트랜잭션이 롤백됩니다." 오류가 발생 하였습니다. 

XACT_ABORT가 ON 상태에서 명시적으로 트랜잭션이 시작되고, TRY 내에서 예외 발생이 되었으나 CATCH에서 트랜잭션에 대하여 롤백 처리를 하지 않고 일괄처리가 끝나면 위와 같은 오류가 발생하게 됩니다.

이제는 오류 메시지가 무슨 의미인지 이해가 될 것입니다.

참고로 ④에서 XACT_STATE()를 사용하고 있는데 반환값이 -1 이면 활성 사용자 트랜잭션이 있지만 오류가 발생하여 트랜잭션이 커밋할 수 없는 상태라는 의미 입니다.
만약 이 상태에서 CATCH 내에서 ROLLBACK이 아닌 COMMIT을 시도하게 되면 다음과 같은 오류가 발생 합니다.

현재 트랜잭션은 커밋할 수 없으며 로그 파일에 쓰는 작업을 지원하지 않습니다. 트랜잭션을 롤백하십시오

이 글이 도움이 되셨으면 추천과 댓글을 부탁 드려요!

반응형
  • BOX(container) 및 Item 들을 열과 행에 자유자재로 나타내기 위한 CSS 기술
  • 예전에는 layout을 위해 table, float tag를 사용 했으나 현재는 flexbox로 모두 대체 가능
  • 서로 다른 screen size 에서 HTML 요소들의 재배치를 통해서 반응형 웹 구현 가능

1. main axis, cross axis 개념

  • 횡(가로)을 중심축으로 하면 직각으로 대응되는 종(세로)이 반대축이 된다.

  • 종(세로)을 중심축으로 하면 직각으로 대응되는 횡(가로)이 반대축이 된다.

2. single line, multi line 개념

  • multi line은 flex-basis 값과 flex-wrap:wrap 속성에 의해 한 줄로 표현하기에 빈 공간이 모자라는 경우 발생

3. container에 적용되는 속성

  • display: flexbox를 쓰기 위하여 flex로 지정
  • flex-direction: main 축 기준으로 각 item이 놓여지는 방향 (row, column, row-reverse, column-reverse)
  • flex-wrap: 한 줄에 item이 지정된 크기를 유지할 수 없을만큼 꽉 찼을 떄 자동으로 행 분리 여부 (nowrap, wrap,wrap-reverse).
    default인 nowrap인 경우에는 item의 크기를 줄여서 한 행을 유지.
  • flex-flow: flex-direction 과 flex-wrap 속성값을 한꺼번에 지정 가능
  • justify-content: 중심축을 기준으로 각 item 사이의 간격 및 부모 box와의 간격 (flex-start, flex-end, center, space-around, space-evenly, space-between)

justify-content

  • align-items: 반대축에서 item을 어떻게 정렬할 지 (stretch, flex-start, flex-end, center, baseline, stretch)

align-items

  • align-content: 반대축에서 item을 어떻게 배치할 지 (stretch, flex-start, flex-end, center, space-around, space-evenly, space-between)

align-content

4. item에 적용되는 속성

  • order: HTML tag가 나오는 순서와 관계 없이 item이 나열되는 순서를  임의로 변경할 때 숫자 지정
  • flex-grow: container가 늘어날 때 width 크기에 맞춰서 한 줄을 꽉 채우도록 item의 크기를 늘릴 비례값(숫자) 지정(기본값 0)

flex-grow

  • flex-shrink: flex-grow와 반대로 container가 줄어들 때 width 크기에 맞춰서 item의 크기를 줄일 비례값(숫자) 지정(기본값 1)
  • flex-basis: 기본 값 auto(grow, shrink에 지정된 값 이용). grow, shrink 없이 basis에 비율('%')로 값을 지정
  • flex: grow, shrink, basis를 한꺼번에 지정
  • align-self: container 지정값(justify-content, align-items, align-content)을 벗어나 item 독자적으로 배치 (center, flex-start, flex-end)

align-self

* 본문 내 이미지 일부는 css-tricks.com/snippets/css/a-guide-to-flexbox/ 에서 capture 함.
 
반응형

javascript에서는 함수를 3가지 방법으로 정의할 수 있습니다.

1. Function 생성자 함수 이용

let add = Function('a', 'b', 'return a + b;');

console.log(add(10, 20));

가장 일반적이지 않은 방법으로서 실무적으로는 사용할 일이 거의 없을 것 같습니다. 다만 다른 함수정의 방식으로 함수를 생성하더라도 내부적으로는 생성자 함수를 통해서 함수가 만들어지게 됩니다. 때문에 javascript에서 모든 함수는 그 자체로 객체 입니다.

2. 함수 선언문 이용

function add(a, b)
{
  return a + b;
}

console.log(add(10, 20));

function 다음에 함수명을 반드시 포함해야 하며, 이 이름으로 함수를 호출할 수 있습니다. 함수 선언문을 이용해 함수를 정의하면 함수 호이스팅(function hoisting)이 일어납니다. 함수 호이스팅은 함수 정의를 소스 유효범위 내 가장 위로 끌어 올리는 것을 말합니다.
그래서 다음과 같이 함수 정의를 하기 전에 함수를 사용하더라도 오류가 발생하지 않습니다.

console.log(add(10, 20));

function add(a, b)
{
  return a + b;
}

3. 함수 표현식 이용

let add = function (a, b)
{
  return a + b;
}

console.log(add(10, 20));

function 다음에 함수명이 없는 익명 함수 리터럴을 사용할 수 있으며 이를 변수에 할당하여 함수를 생성 합니다.
할당된 변수이름 뒤에 괄호를 붙여서 함수 호출을 할 수 있습니다.
이 경우에는 함수 호이스팅이 일어나지 않아서 만약 함수 정의 전에 함수를 사용하면 오류가 발생 합니다.

일반적으로는 익명 함수 형태로 사용하며 함수 내에서 재귀 호출이 필요한 경우에는 다음과 같이 함수명을 사용할 수도 있습니다. 다만 이때의 함수명은 함수 정의 밖에서는 사용할 수 없습니다.

let factorial = function _factorial (num)
{
  if (num > 1)
  {
    return num * _factorial(num - 1);
  }
  else
  {
    return 1;
  }
}

console.log(factorial(5));  // 120
console.log(_factorial(5)); // not defined 에러

 

+ Recent posts